shell
The Uses of the Exec Command in Shell Script
Shell
示例: wget http://soft.vpser.net/lnmp/lnmp1.8-full.tar.gz (lnmp下载地址:https://lnmp.org/download.html) #!/bin/sh #!/bin/bash sh是早期linux shell, bash是为GNU编写的unix shell, 兼容sh sh遵循posix规范,代码出错时,不再往下运行; bash 代码出错,还将继续运行 查看当着shell echo $SHELL 查看已安装的shell cat /etc/shell 切换shell chsh -s /bin/bash chsh -s /bin/zsh bash与zsh的区别 bash读取 ~/bash_profile zsh 读取 ~/zshrc !.注意空格和引号 2.注意数组index不同 3.使用一个等号,避免使用短if语句
Bash
参数缺省值 ${1-} ${1:-2} ${parameter-default}, ${parameter:-default} If parameter not set, use default. 左移参数 while [ $# -ne 0 ]; do if [ $1 == 'install' ]; then break fi shift done 1>/dev/null 2>&1的含义 command printf %s\\n "Failed mark .nvm/nvm_exec as excutable" >&2 #输出标准错误信息 > 代表重定向到哪里 0 表示键盘输入(stdin) 1 表示stdout标准输出,系统默认值是1,所以">/dev/null"等同于"1>/dev/null" 2 表示stderr标准错误 & 表示等同于的意思,2>&1,表示2的输出重定向等同于1 EOF用法: case "$i" in -d*) options=$options" --debug";; -v*) VERBOSE="true";; -h*) DRYRUN="true"; cat <<EOF Usage: config [options] -d Build with debugging when possible. -v Verbose mode, show the exact Configure call that is being made. -h This help. EOF ;; esac 带变量多行显示 echo /usr/bin/env \ __CNF_CPPDEFINES="'$__CNF_CPPDEFINES'" \ __CNF_CPPINCLUDES="'$__CNF_CPPINCLUDES'" \ $PERL $THERE/Configure $OUT $options 布尔: = and == are for string comparisons -eq is for numeric comparisons $ a=foo $ [ "$a" = foo ]; echo "$?" # POSIX sh 0 $ [ "$a" == foo ]; echo "$?" # bash-specific 0 $ [ "$a" -eq foo ]; echo "$?" # wrong -bash: [: foo: integer expression expected 2 显示进度(echo -e 转义 -n 不换行) echo -ne '##### (33%)\r' sleep 1 echo -ne '############# (66%)\r' sleep 1 echo -ne '####################### (100%)\r' echo -ne '\n' 表格格式化列数据 column -t < a.dat > a.txt exec命令 $ bash $ exec > file $ date $ exit $ cat file Thu 18 Sep 2014 23:56:25 CEST
命令行
$0 :即命令本身,相当于c/c++中的argv[0] $1 :第一个参数. $2, $3, $4 ... :第2、3、4个参数,依次类推。 $# :参数的个数,不包括命令本身 $@ :参数本身的列表,也不包括命令本身 $* :"$*"将所有的参数解释成一个字符串,而"$@"是一个参数数组。 $$ :当前shell进程ID $? :获取上一个命令的退出状态 $() ``(反引号)作命令行使用 ${} 变量边界, $var和${var}相同, $[] $(()) 进行整数数学计算; $[a+b*c%d] [] 测试, [ -f /etc/bashrc ], 括号内要加空格 (()) 符合C语言规则, ((i++)) for((i=0;i<10;i++ )) [[]] 参数扩展和命令替换, [[ $res=~'hello' ]] 数组: arr=(1,2,3,4,5) for i in ${arr[@]) do echo $i if [ $i -lt 4 ]: then continue fi echo '----' done 数组长度: arrLen=${#arr[@]} 删除数组: unset arr[1] 关联数组: declare -A site; site["google"]="www.google.com" site["runoob"]="www.runoob.com" site["taobao"]="www.taobao.com" 或: declare -A site(["google"]="www.google.com" ["runoob"]="www.runoob.com" ["runoob"]="www.runoob.com") eval函数 pip="|" eval ls $pipe wc -l #二次扫描 eval echo \$$# #显示最后一个参数,第一次扫描$#为参数个数 指针作用 x=100 ptr=x eval echo $ptr eval $ptr=60 echo $x #显示60
语法
if [ -f /etc/resolv.conf ];then echo "$FILE exist" else echo "$FILE does not exist" fi 等价于: [ -f /etc/resolv.conf ] && echo "$FILE exist" || echo "$FILE does not exist" 执行多个命令: [ -f /etc/resolv.conf ] && (echo "$FILE exist"; cp "$FILE" /tmp/;) 判断文件可执行: [ -x /etc/resolv.conf ] && echo "$FILE can excute" function test() { echo 'input param1: '$1 echo 'input param1: '$2 return 100 #返回值必须是数值 } 运行: test hello world echo "test return value is: "$? res=$(test 'hello' 'world') #读取echo返回值 echo "test 'hello' 'world' return is --> "$res if [[ $res =~ 'hello' ]]; then echo 'output having "hello"' fi 输出: input param1: hello input param1: world test return value is: 100 test 'hello' 'world' return is --> input param1: hello input param2 is: world output having "hello" for a in {1..10} do echo $a done for file in ${ls ~/} do echo $file done 函数内局部变量 local EACH_PROFILE for EACH_PROFILE in ".bashrc" ".bash_profile" ".zprofile" ".zshrc" do echo $EACH_PROFILE done a=1 while ((a<9)) do echo $i let i++ done while read line do echo $line done < ~/.ssh/config read -p "Continue? (Y/N): " confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] || exit 1 read -p "choice yes/no: " yes case $yes in y) echo 'choice Y' ;; n|c) echo 'choice N' ;; *) echo 'choice unknown' ;; esac read -p "Continue? (Y/N): " confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] && (echo "ok!"; echo "exit...") || exit 1 read -p "Reboot now? (Y/N): " confirm if [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]]; then reboot now elif [[ $confirm == [cC] ]]: then exit 1 fi 检测是否安装 type python >/dev/null 2>&1 echo $? if ! type python >/dev/null 2>&1; then echo 'python no installed!' fi 检测命令是否执行成功 if [ $? -eq 0 ]; then echo 'execute success' else echo 'execute error' fi
字符串
#删除左边字符,保留右边的字符 %删除右边字符,保留左边的字符 str="http://www.baidu.com/123.html" echo ${str#$*//} #www.baidu.com/123.html echo ${str##*/} #123.html echo ${str%/*} #http://www.baidu.com echo ${str%%/*} #http: echo ${str:0:5} #http: echo ${str:7} #www.baidu.com/123.html echo ${str:0-8:3} #123 echo ${str:0-8} #123.html name="shell" url="http://www.baidu.com" str1=$name$url #中间不能有空格 str2="$name $url" #如果被双引号包围,那么中间可以有空格 str3=$name": "$url #中间可以出现别的字符串 str4="$name: $url" #这样写也可以 str5="${name}Script: ${url}index.html" echo $str1 #shellhttp://www.baidu.com echo $str2 #shell http://www.baidu.com echo $str3 #shell:http://www.baidu.com
文件属性
if [ -f $file ]: then rm $file fi if [ ! -d $path ]: then mkdir $path fi -e 判断对象是否存在 -d 判断对象是否存在,并且为目录 -f 判断对象是否存在,并且为常规文件 -L 判断对象是否存在,并且为符号链接 -h 判断对象是否存在,并且为软链接 -s 判断对象是否存在,并且长度不为0 -r 判断对象是否存在,并且可读 -w 判断对象是否存在,并且可写 -x 判断对象是否存在,并且可执行 -O 判断对象是否存在,并且属于当前用户 -G 判断对象是否存在,并且属于当前用户组 -nt 判断file1是否比file2新 [ "/data/file1" -nt "/data/file2" ] -ot 判断file1是否比file2旧 [ "/data/file1" -ot "/data/file2" ] 常见的环境变量: PATH: 决定了shell将到哪些目录中寻找命令或程序 ROOTPATH: 这个变量的功能和PATH相同,但它只罗列出超级用户(root)键入命令时所需检查的目录 HOME: 当前用户主目录 USER: 查看当前的用户 LOGNAME: 查看当前用户的登录名。 UID: 当前用户的识别字,取值是由数位构成的字串。 SHELL: 是指当前用户用的是哪种Shell。 TERM: 终端的类型 PWD: 当前工作目录的绝对路径名 MAIL: 是指当前用户的邮件存放目录: HISTSIZE: 是指保存历史命令记录的条数 HOSTNAME: 是指主机的名称 PS1: 是基本提示符,对于root用户是#,对于普通用户是$ PS2: 是附属提示符,默认是">”。 IFS: 输入域分隔符。当shell读取输入时,用来分隔单词的一组字符,它们通常是空格、制表符和换行符
参数 | 说明 | 示例 |
-eq | 等于则为真 | if [ $var1 -eq 100 ] |
-ne | 不等于则为真 | if [ $var1 -ne 100 ] |
-gt | 大于则为真 | if [ $var1 -gt 100 ] |
-ge | 大于等于则为真 | if [ $var1 -ge 100 ] |
-lt | 小于则为真 | if [ $var1 -lt 100 ] |
-le | 小于等于则为真 | if [ $var1 -le 100 ] |
== | 相等则为真 | if [ \(var1 == \)var2 ] |
!= | 不相等则为真 | if [ \(var1 != \)var2 ] |
=~ | 前边变量包含后边变量则为真 | if [ \(var1 =~ \)var2 ] |
-z 字符串 | 字符串的长度为零则为真 | if [ -z $var1 ] |
-n 字符串 | 字符串的长度不为零则为真 | if [ -n $var1 ] |