一基础:
echo $PATH #获取环境变量路径 echo $SHELL #获取默认shell默认使用环境变量
创建xx.sh并执行
#在环境路径下建立xx.sh文件内容如下 #!/bin/bash #约定脚本使用的解释器 #范例脚本 echo "what is your name" read person #这里使用read命令获取stdin命令窗口输入内容获取变量 echo "hello,$person" #写完后保存 #给予权限 chmod -x xx.sh #提示:w:读 r:写 x:执行 #完成后执行,切记一定要./开头: ./xx.sh
二:变量
#切记,区别于php,变量赋值左右不能有空格,一定要注意,但是运算必须有空格 #变量声明如下,明明规范等于php,默认Bash shell都会识别为字符串,如果值包含空格等必须使用引号包围 variable=value variable='value' variable="value" #使用如下,{}是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界 #推荐给所有变量加上花括号{ },这是个良好的编程习惯。 author="严长生" echo $author echo ${author} skill="Java" echo "I am good at ${skill}Script" #和php一样,变量可以被重新赋值 url="aa" echo ${url} url="bb" echo ${url} #值的引号使用等于php,单引号不解析变量,且不转义字符,双引号解析变量可以转义字符,所以如果不是原样输出,没有特殊需要最好都用双引号 #变量的赋值有两种,推荐使用第二种,如下 log=`cat test.txt` #使用反引号,用以和单引号混淆 echo $log log=$(cat test.txt) #使用()号,推荐使用 echo $log #只读变量 readonly url="aa" url="bb" #会报错:url: readonly variable #删除变量使用unset,等于php url="aa" unset url #变量类型 #运行shell时,会同时存在三种变量: #1) 局部变量 #局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。 #2) 环境变量 #所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。 #3) shell变量 #shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行 */
特殊变量,可echo 测试:
$0 | 当前脚本的文件名 |
$n | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 |
$# | 传递给脚本或函数的参数个数。 |
$* | 传递给脚本或函数的所有参数。 |
$@ | 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。 |
$ | 上个命令的退出状态,或函数的返回值。 |
$$ | 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。 |
#!/bin/sh echo "sh name:$0" echo "fist param:$1" echo "two param:$2" echo "all param:$@" echo "all param:$*" echo "param number:$#" #输入命令,在执行的脚本命令后边传递参数: ./dir.sh A B #或者后面跟字符串./test.sh "a" "b" "c" "d" #输出如下: sh name:./dir.sh fist param:A two param:B all param:A B all param:A B param number:2 # $* 和 $@ 的区别,他们不被双引号包含时都是以$1,$2输出所有参数 echo "\$*=" $* echo "\"\$*\"=" "$*" #在对双引号包含的"$*"进行for循环时,会将参数当一个整体输出(可理解为字符串) echo "\$@=" $@ echo "\"\$@\"=" "$@" #举例: ./test.sh "a" "b" "c" "d" #for "$*"时 会将参数作为一个整体全部输出,而不是每个参数 #退出状态 echo $ #在脚本里执行输出上一个命令执行后的返回结果,大部分命令执行成功会返回 0,失败返回 1
Shell替换:Shell变量替换,命令替换,转义字符:
转义字符 |
含义 |
\\ | 反斜线 |
\a | 警报、响铃 |
\b | 退格(删除键) |
\f | 换页(FF),将当前位置移到下页开头 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符(tab键) |
\v | 垂直制表符 |
#如果输出内容里包含转义字符 a=10 echo -e "value of a is $a \n" #这里加上-e 表示对转义字符进行替换,表示输出的结尾加上换行 value of a is 10 #如果这里不加上-e的话,则会原样输出: value of a is 10\n #可以使用 echo 命令的 -E 选项禁止转义,默认也是不转义的;使用 -n 选项可以禁止插入换行符。 #命令替换
变量替换表,相当于php某些框架中模板中输出变量的用法
形式 | 说明 |
---|---|
${var} | 变量本来的值 |
${var:-word} | 如果变量 var 为空或已被删除(unset),那么返回word,但不改变var 的值。 |
${var:=word} | 如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。 |
${var:message} | 如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。 若此替换出现在Shell脚本中,那么脚本将停止运行。 |
${var:+word} | 如果变量 var 被定义,那么返回 word,但不改变 var 的值。 |
shell运算符
#原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。 #expr 是一款表达式计算工具,使用它能完成表达式的求值操作。 #注意两点: #一:表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2 #二:完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。 #例如 #!/bin/bash val=`expr 2 + 2` echo $val a=10 b=20 val=`expr $a \* $b` echo "a * b : $val" if [ $a != $b ] then echo "a is not equal to b" fi #乘号(*)前边必须加反斜杠(\)才能实现乘法运算;
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | `expr $a + $b` 结果为30。 |
- | 减法 | `expr $a - $b` 结果为 10。 |
* | 乘法 | `expr $a \* $b` 结果为 200。 |
/ | 除法 | `expr $b / $a` 结果为2。 |
% | 取余 | `expr $b % $a` 结果为0。 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
关系运算符列表
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
运算符 说明 举例 -eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回true。 -ne 检测两个数是否相等,不相等返回 true。 [ $a -ne $b ] 返回 true。 -gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。 -lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。 -ge 检测左边的数是否大等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。 -le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。
a=10 b=20 if [ $a -eq $b ] #注意啊,这里[]两边必须空格,否则报错 then echo "$a -eq $b : a is equal to b" else echo "$a -eq $b: a is not equal to b" fi
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回false。 |
#!/bin/sh a=10 b=20 if [ $a -lt 100 -a $b -gt 15 ] then echo "$a -lt 100 -a $b -gt 15 : returns true" else echo "$a -lt 100 -a $b -gt 15 : returns false" fi #输出 10 -lt 100 -a 20 -gt 15 : returns true
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否相等,不相等返回 true。 | [ $a != $b ] 返回true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否为0,不为0返回 true。 | [ -z $a ] 返回 true。 |
str | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回true。 |
Shell字符串
#字符串拼接 a="this is a" b="fllow,"$a"!" c="fllow,${a} !" echo $b $c #输出内容如下: fllow,this is a! fllow,this is a ! #获取字符串长度 string='abcd' echo ${#string} #输出 4 #提取子字符串 string="alibaba is a great company" echo ${string:1:4} #输出liba,也就是第1-第四的字符
Shell数组:shell数组的定义、数组长度
#shell中数组和php有点类似,没有多维数组,定义时用(),值与值之间用空格分开,读取时用下标,下标也是0开始 array=(a b c d) array=( a b c d ) array[0]=a array[1]=b array[2]=c array[3]=d #读取格式为 ${array[0]} #使用*和@可以获取数组中所有元素 ${array[*]} ${array[@]} #获取数组长度 ${#array[*]} ${#array[@]} @获取数组单个元素的长度 ${#array[n]}
Shell if else语句,三种用法
#第一种 if [ $a == $b ] then echo "a is equal to b" fi #第二种 if [ $a == $b ] then echo "a is equal to b" else echo "a is not equal to b" fi #第三种 a=10 b=20 if [ $a == $b ] then echo "a is equal to b" elif [ $a -gt $b ] then echo "a is greater than b" elif [ $a -lt $b ] then echo "a is less than b" else echo "None of the condition met" fi
Shell test命令
# test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。 #数值 num1=100 num2=100 if test $[num1] -eq $[num2] then echo 'The two numbers are equal!' else echo 'The two numbers are not equal!' fi #字符串 num1=100 num2=100 if test num1=num2 then echo 'The two strings are equal!' else echo 'The two strings are not equal!' fi #文件测试,比较命令请参考文档 cd /bin if test -e ./notFile -o ./bash then echo 'One file exists at least!' else echo 'Both dose not exists!' fi #与( ! )、或( -o )、非( -a )三个逻辑操作符用于将测试条件连接起来,其优先级为:“!”最高,“-a”次之,“-o”最低。例如:
Shell case esac语句
#直接举例吧 #其间所有命令开始执行直至 ;;。 ;; 与其他语言中的 break 类似 echo 'Input a number between 1 to 4' echo 'Your number is:\c' read aNum case $aNum in 1) echo 'You select 1' ;; 2) echo 'You select 2' ;; 3) echo 'You select 3' ;; 4) echo 'You select 4' ;; *) echo 'You do not select a number between 1 to 4' ;; esac option="${1}" case ${option} in -f) FILE="${2}" echo "File name is $FILE" ;; -d) DIR="${2}" echo "Dir name is $DIR" ;; *) echo "`basename ${0}`:usage: [-f file] | [-d directory]" exit 1 # Command to come out of the program with status 1 ;; esac
Shell for循环
#直接上例子,列表是一组值(数字、字符串等)组成的序列,每个值通过空格分隔 for loop in 1 2 3 4 5 do echo "The value is: $loop" done #结果 The value is: 1 The value is: 2 The value is: 3 The value is: 4 The value is: 5 #顺序输出字符串中的字符 for str in 'This is a string' do echo $str done #运行结果: This is a string #显示主目录下以 .bash 开头的文件: for FILE in $HOME/.bash* do echo $FILE done #结果 /root/.bash_history /root/.bash_logout /root/.bash_profile /root/.bashrc
Shell while循环
#例子 count=1 while [ $count -lt 6 ] do echo $count let count++ done #输出 1 2 3 4 5 6 #读取磁盘信息 echo 'typeto terminate' echo -n 'enter your most liked film: ' while read FILM do echo "Yeah! great film the $FILM" done
Shell until循环,和while相反,遇到true时才停止
#和while一样,循环里运算用法要注意 #输出 0 ~ 9 的数字 a=0 until [ ! $a -lt 10 ] do echo $a let ++a done
break命令
#像大多数编程语言一样,Shell也使用 break 和 continue 来跳出循环。 while : do echo -n "input your number between 1 to 5" read num case $num in 1|2|3|4|5) echo "your number is $num" ;; *) echo 'stop' break ;; esac done #和php一样,满足条件break跳出循环 break n跳出第几层循环 for var1 in 1 2 3 do for var2 in 0 5 do if [ $var1 -eq 2 -a $var2 -eq 0 ] then break 2 else echo "$var1 $var2" fi done done #coutinue表示跳出本次循环 coutinue n跳出第几层循环 while : do echo -n "Input a number between 1 to 5: " read aNum case $aNum in 1|2|3|4|5) echo "Your number is $aNum!" ;; *) echo "You do not select a number between 1 to 5!" continue echo "Game is over!" ;; esac done
Shell函数:Shell函数返回值、删除函数、在终端调用函数
#可以带function 也可以不带,调用时后面不需要() #实例 number_one () { echo "Url_1 is http://see.xidian.edu.cn/cpp/shell/" number_two } number_two () { echo "Url_2 is http://see.xidian.edu.cn/cpp/u/xitong/" } number_one #使用函数接受结果请使用$ funWithReturn(){ echo "The function is to get the sum of two numbers..." echo -n "Input first number: " read aNum echo -n "Input another number: " read anotherNum echo "The two numbers are $aNum and $anotherNum !" return $(($aNum+$anotherNum)) } funWithReturn # Capture value returnd by last command ret=$ echo "The sum of two numbers is $ret !" #删除函数 unset .f function_name #/etc/profile #可以将函数定义在以上目录,这样每次登录后,在命令提示符后面输入函数名字就可以立即调用
Shell函数参数
#通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数... funWithParam(){ echo "The value of the first parameter is $1 !" echo "The value of the second parameter is $2 !" echo "The value of the tenth parameter is $10 !" echo "The value of the tenth parameter is ${10} !" echo "The value of the eleventh parameter is ${11} !" echo "The amount of the parameters is $# !" # 参数个数 echo "The string of the parameters is $* !" # 传递给函数的所有参数 } funWithParam 1 2 3 4 5 6 7 8 9 34 73 #注意:注意,当n>=10时,需要使用${n}来获取参数 #前面讲过特殊变量,$*:参数个数,$*和$@获取所有参数
Shell输入输出重定向:Shell Here Document,/dev/null文件
#Unix 命令默认从标准输入设备(stdin)获取输入,将结果输出到标准输出设备(stdout)显示。一般情况下,标准输入设备就是键盘,标准输出设备就是终端,即显示器。 #命令的输出不仅可以是显示器,还可以很容易的转移向到文件,这被称为输出重定向。 #输出重定向 用> echo line 1 > users #输出重定向会覆盖文件内容 echo line 2 >> users #使用 >> 追加到文件末尾 #查看 cat users #输入重定向,可以从文件获取输入 用< #计算 users 文件中的行数 wc -l users #输入重定向到 users 文件 wc -l < users #如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null: #如果希望屏蔽 stdout 和 stderr,可以这样写: command > /dev/null 2>&1
命令 | 说明 |
---|---|
command > file | 将输出重定向到 file。 |
command < file | 将输入重定向到 file。 |
command >> file | 将输出以追加的方式重定向到 file。 |
n > file | 将文件描述符为 n 的文件重定向到 file。 |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 |
n >& m | 将输出文件 m 和 n 合并。 |
n <& m | 将输入文件 m 和 n 合并。 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |
Shell文件包含
#包含外部脚本,将外部脚本的内容合并到当前脚本。 #一种 . filename #简单起见,一般使用点号(.),但是注意点号(.)和文件名中间有一空格 #二种 source filename #注意:被包含脚本不需要有执行权限。 #在相同目录创建url.sh,内容为 a='thi s inlcude strinf' #在使用test.sh . ./url.sh echo $a #即可