shell编程核心知识点

来源:互联网 发布:java.util.scanner错误 编辑:程序博客网 时间:2024/05/24 01:42

1、 执行脚本source和./的区别

source执行脚本时,不会创建子进程,而是在父进程中直接执行,如果脚本中有改变环境变量等操作,会影响到父进程的shell窗口,而 ./ 则不会。

2、替换运算符

${varname:-word} 如果varname存在且非null,则返回varname的值;否则,返回word。
用途:如果变量未定义,则返回默认值。
范例:如果loginname未定义,则${loginname:-ollir}的值为ollir。 ${varname:=word} 如果varname存在且非null, 则返回varname的值,否则,设置其为word,然后返回其设置的值。
用途:如果变量未定义,则设置变量为word,并返回。
范例:如果loginname未定义,则${loginname:-ollir}的值为ollir,并且loginname变量被设置为ollir ${varname:?message} 如果varname存在且非null,则返回varname的值,否则,打印“varname:message”,并退出当前的命令或脚本。如果省略message,shell会返回默认信息“parameter null or not set”。
用途:常用于捕获由于变量未定义而导致的错误。
范例:如果loginname未定义,则${loginname:?”undefined!”}则显示为loginname: undefined!,然后退出脚本。 ${varname:+word} 如果varname存在且非null,则返回word,否则返回null。用途:测试变量的存在性。
范例:如果loginname已定义,如${loginname:+1},返回1(也就真)

上述运算符内的冒号(:)是可选的。如果省略,则上述解释中的“存在且非null”改为“存在”即可,即变量运算符只判定变量是否存在。

3、模式匹配运算符

假设path的值为/home/prince/desktop/log.file.name

${varname#pattern} 如果模式匹配于变量的开头处,则删除匹配的最短部分,并返回剩下的部分。
范例:${path#/*/}为prince/desktop/log.file.name
这个范例删除了字符串开头/之间的部分
${path#*/}为home/prince/desktop/log.file.name
${path#*.}为file.name ${varname##pattern} 如果模式匹配于变量的开头处,则删除匹配的最长部分,并返回剩下的部分。
范例:${path##/*/}为log.file.name
这个范例提取了文件路径中的文件名
${path##*/}为log.file.name
${path##*.}为name ${varname%pattern} 如果模式匹配于变量的结尾处,则删除匹配的最短部分,并返回剩下的部分。
范例:${path%/*}为/home/prince/desktop
${path%.*}为/home/prince/desktop/log.file ${varname%%pattern} 如果模式匹配于变量的结尾处,则删除匹配的最长部分,并返回剩下的部分。
范例:${path%%.*}为/home/prince/desktop/log ${varname/pattern/string}
${varname//pattern/string} 将varname中匹配模式的最长部分替换为string。
第一种格式中,只有匹配的第一部分被替换;第二种格式中,varname中所有匹配的部分都被替换。如果模式以#开头,则必须匹配varname的开头,如果模式以%开头,则必须匹配varname的结尾。如果string为空,则匹配部分被删除。如果varname为@或者*,操作被依次应用于每个位置参数,并且扩展为结果列表。
范例:${path//prince/ollir}则为:
/home/ollir/desktop/log.file.name
这个范例将字符串prince替换为ollir

4、shell中的常见参数引用

$0, $1, $2, ...表示系统传给脚本程序或脚本程序传给函数的第 0个、第1个、第2个等参数。其中 $0表示 shell  文件的名称。$# 表示脚本程序的命令参数个数或函数的参数个数$? 表示脚本程序或函数的返回状态值,正常为0,否则为非零的错误号$*以一个单字符串显示所有向脚本传递的参数。如"$*"用「"」括起来的情况、以"$1 $2$n"的形式输出所有参数。$@与$*相同,但是使用时加引号,并在引号中返回每个参数。如"$@"用「"」括起来的情况、以"$1" "$2""$n" 的形式输出所有参数。$$    脚本运行的当前进程ID号$! 后台运行的最后一个进程的ID号$- 显示Shell使用的当前选项,与set命令功能相同

$* 与 $@ 区别:

  • 相同点:都是引用所有参数。
  • 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 ” * ” 等价于 “1 2 3”(传递了一个参数),而 “@” 等价于 “1” “2” “3”(传递了三个参数)。

实例分析

    #!/bin/bash    echo "-- \$* 演示 ---"    for i in "$*"; do        echo $i    done    echo "-- \$@ 演示 ---"    for i in "$@"; do        echo $i    done
执行脚本,输出结果如下所示:$ chmod +x test.sh $ ./test.sh 1 2 3-- $* 演示 ---1 2 3-- $@ 演示 ---123

5、数组

使用@ 或 * 可以获取数组中的所有元素,例如${my_array[*]}、${my_array[@]}
使用#获取数组的长度,要配合@或一起使用,例如${#my_array[]}、${#my_array[@]}

$()的用法
利用 $() 符号可以把一个命令的执行结果赋值给变量

6、算术运算

当把一个算术表达式的结果赋值给一个变量是不行的。

~]# a=1+2 ~]# echo $a 1+2 

而应该采取下面几种方式之一:

~]# let a=1+2 ~]# echo $a 3 ~]# a=$((2+3)) ~]# echo $a 5 ~]#  declare -i a ~]#  a=10+1 ~]# echo $a 11

假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例
+ 加法 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。

7、关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例

-eq 等于  [ $a -eq $b ] 返回 false-ne 不等于 [ $a -ne $b ] 返回 true-gt 大于, [ $a -gt $b ] 返回 false-lt 小于  [ $a -lt $b ] 返回 true。-ge 大于等于    [ $a -ge $b ] 返回 false。-le 小于等于    [ $a -le $b ] 返回 true。<   小于 (需要双括号 ),    如:(("$a" < "$b"))  <=      小于等于 (需要双括号 ),  如:(("$a" <= "$b"))  >   大于 (需要双括号 ),    如:(("$a" > "$b"))  >=      大于等于 (需要双括号 ),  如:(("$a" >= "$b"))

8、布尔运算符

下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例

!   非运算,表达式为 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

9、逻辑运算符

以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例

&&  逻辑的AND  [[ $a -lt 100 && $b -gt 100 ]] 返回 false||  逻辑的OR   [[ $a -lt 100 || $b -gt 100 ]] 返回 true

10、字符串运算符

下表列出了常用的字符串运算符,假定变量 a 为 “abc”,变量 b 为 “efg”:
运算符 说明 举例

=或者==   检测两个字符串是否相等,相等返回 true。[ $a = $b ]返回false。!=       检测两个字符串是否相等,不相等返回 true。[ $a != $b ] 返回true。<        检验左边的字符串是否小于右边的,只能用于[[ ]]中,[[ $a < $b ]]或者[ $a \< $b ]返回true>        与<效果相反 ,只能用于 [[ ]] 中,[[ $a < $b ]]或者[ $a \> $b ]返回false-z       检测字符串长度是否为0(是否为空),为0返回 true。[ -z $a ] 返回 false。-n       检测字符串长度是否为0(是否非空),不为0返回 true。[ -n $a ] 返回 true。str      检测字符串是否为空,不为空返回 true。[ $a ] 返回 true

11、文件测试运算符

文件测试运算符用于检测 Unix 文件的各种属性。
操作符 说明 举例

-b file 检测文件是否是块设备文件,如果是,则返回 true。  [ -b $file ] 返回 false-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false-d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。    [ -f $file ] 返回 true-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。  [ -g $file ] 返回 false-h file 检测文件是否为符号链接,如果是,则返回true -L file 同-h -k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。  [ -k $file ] 返回 false-p file 检测文件是否是有名管道,如果是,则返回 true。   [ -p $file ] 返回 false-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。  [ -u $file ] 返回 false-r file 检测文件是否可读,如果是,则返回 true。  [ -r $file ] 返回 true-w file 检测文件是否可写,如果是,则返回 true。  [ -w $file ] 返回 true-x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true-S file 检测文件是否为套接字(socket),如果是,返回true   -s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true-e file 检测文件(包括目录)是否存在,如果是,则返回 true。    [ -e $file ] 返回 true-O file 检测你是否是文件的所有者,如果是,返回true -G file 检测文件的组ID是否匹配你的ID,如果是,返回true file1 –nt file2 检测file1是否比file2新,如果是,返回true file1 –ot file2 检测file1是否比file2旧,如果是,返回true 

12、if语句

使用 if 语句的语法格式如下:

if condition1_test; then   action elif condition2_test; then   action fi 

在 bash shell 程序中,条件测试是一个完整的语句,当与 then在同一行使用的时候,要加分号。如果条件测试和 then 分为两行,则可以不用加分号而使用下面的语句形式。

if condition1_test then action1 elif condition2_test then action2 fi 

条件测试部分的逻辑表达式可以有下面几种方式:

  • 放置在 test 关键字之后、
  • 放置于 [ ]中、
  • 放置于 [[ ]] 中、
  • 放置于 (( )) 中。

其中 test 条件 等价于 [ ] 的用法。 [ ] 及 [[ ]] 可以放置字符串比较逻辑表达式、文件判断表达式以及数值条件表达式,使用时,注意逻辑运算符两侧及判断表达式两侧要留有空格,而 (( )) 用于数值比较逻辑表达式。在用法上, ksh 一般使用 [[ ]] 及 (( )) ,bash shell 对这几种用法都支持,一般使用 [ ] 。

13、case语句

语法:

case var in     var变量    patten 1)   匹配模式1 a|b|c  |or类似    command...  需要执行的命令    ;;      命令执行完毕    patten 2)    command...    ;;    *)      默认值,没有匹配的模式    command...      ;;esac

14、for循环

语法

for name [in list]    #遍历list中所有的对象do….            #执行与$name相关的操作done

注意in list可以省略,省略时默认是in “$@”,即命令行参数的引用列表

第一类:数字性循环

for1-1.sh#!/bin/bash       for((i=1;i<=10;i++));  do   echo $(expr $i \* 3 + 1);  donefor1-2.sh#!/bin/bash  for i in $(seq 1 10)  do   echo $(expr $i \* 3 + 1);  done  for1-3.sh#!/bin/bash   for i in {1..10}  do  echo $(expr $i \* 3 + 1);  done  for1-4.sh#!/bin/bash  awk 'BEGIN{for(i=1; i<=10; i++) print i}'  

第二类:字符性循环

for2-1.sh#!/bin/bash  for i in `ls`;  do   echo $i is file name\! ;  done  for2-2.sh#!/bin/bash  for i in $* ;  do  echo $i is input chart\! ;  done  for2-3.sh#!/bin/bash  for i in f1 f2 f3 ;  do  echo $i is appoint ;  done  for2-4.sh#!/bin/bash  list="rootfs usr data data2"  for i in $list;  do  echo $i is appoint ;  done  

第三类:路径查找

for3-1.sh#!/bin/bash  for file in /proc/*;  do  echo $file is file path \! ;  done  for3-2.sh#!/bin/bash  for file in $(ls *.sh)  do  echo $file is file path \! ;  done  

14、while/until循环

语法

while conditiondo….doneuntil conditiondo….done

在while语句中,当condition的退出状态为真时,循环继续运行,否则退出循环
在until语句中,当condition的退出状态为真时,退出循环,否则继续执行循环

当循环体的嵌套次数超过1层时,可以传给break或continue参数,来控制它们跳出或者继续几层循环

while condition1             #第一层循环do….while condition2         #第二层循环do    …..    break 2            #跳出两层循环donedone

shift命令
shift处理命令参数时,截取第一个位置参数,而将其他的未知参数左移,$#的值会逐渐减小,shift可以接受可选参数,用以制定一次要移动几位

原创粉丝点击