1. 命令行参数------类似javac 参数1 参数2
类似Java中编译的javac parm1....。在shell中,参数与参数之间用空格隔开。采用位置参数来识别对应的参数值:$0是程序名,$1是第一个参数,以此类推,知道第9个参数$9。对于大于9个参数的需要在变量数字周围添加花括号,比如${10}。
note:命令行上不仅可以处理数值,还可以处理字符串。
1 [Hermioner@localhost Documents]$ cat test2.sh 2 #!/bin/bash 3 total=$[ $1*$2 ] 4 echo The first parm is $1 5 echo The second parm is $2 6 a=$3 7 echo the third parm is $3 8 b=$4 9 echo the forth parm is $4 10 [Hermioner@localhost Documents]$ bash test2.sh 2 3 "hello world" min 11 The first parm is 2 12 The second parm is 3 13 the third parm is hello world 14 the forth parm is min
1 [Hermioner@localhost Documents]$ cat test3 2 #!/bin/bash 3 echo the tenth parm is ${10} 4 echo the eleventh parm is ${11} 5 [Hermioner@localhost Documents]$ bash test3 1 2 3 4 5 6 7 8 9 10 11 6 the tenth parm is 10 7 the eleventh parm is 11 8 [Hermioner@localhost Documents]$
note: $0返回脚本名,如果用bash,就只返回脚本名;如果./脚本来运行,返回当前路径名; 因此,还可以尝试basename命令来返回不包含路径的脚本名。
2. $#,$*,$@,${!#}
s# 用来统计命令行的参数个数
s* 用来访问所有的命令行参数,并且构成一个字符串整体输出
s@ 同s*,只是结果是分散成字符串数组,每个数组中的元素都是一个参数
${!#} 代表的最后一个参数,因为花括号中不可以用$,因此用!来代替它
1 [Hermioner@localhost Documents]$ cat testfile 2 #!/bin/bash 3 echo the "\$*" is $* 4 echo the "\$@" is $@ 5 echo the "\$#" is $# 6 echo the "\${!#}" is ${!#} 7 8 [Hermioner@localhost Documents]$ bash testfile a b c d 9 the $* is a b c d 10 the $@ is a b c d 11 the $# is 4 12 the ${!#} is d
1 [Hermioner@localhost Documents]$ cat testfile 2 #!/bin/bash 3 echo 4 count=1 5 for param in "$*" 6 do 7 echo "\$* Parameter #$count = $param" 8 count=$[ $count+1 ] 9 done 10 11 echo 12 count=1 13 for param in "$@" 14 do 15 echo "\$@ Parameter #$count = $param" 16 count=$[ $count+1 ] 17 done 18 19 [Hermioner@localhost Documents]$ bash testfile a b c d 20 21 $* Parameter #1 = a b c d 22 23 $@ Parameter #1 = a 24 $@ Parameter #2 = b 25 $@ Parameter #3 = c 26 $@ Parameter #4 = d 27 [Hermioner@localhost Documents]$
3. shift 移动变量
shift可以用来在不知道有多少参数,以及每个参数的值的情况下进行遍历,因为它始终可以只打印第一个值。默认情况下它会将每个参数变量向左移动一个位置。所以变量$3的值会移动到$2中,$2的值会移动到$1中,而变量$1的值则会被删除(note:$0代表程序吗,不会改变)
也可以shift n 来指定左移动多少个,eg: shift 2 ,则$3的会移动到$1中,这样就可以跳过一些值不遍历了。
1 [Hermioner@localhost Documents]$ cat test3.sh 2 #!/bin/bash 3 echo "the original parameters is $*" 4 shift 2 5 echo "the new first parameter is $1" 6 [Hermioner@localhost Documents]$ bash test3.sh 1 2 3 4 5 7 the original parameters is 1 2 3 4 5 8 the new first parameter is 3 9 [Hermioner@localhost Documents]$
note:配合shift的使用,同样可以通过shell脚本中的逻辑来判断是选项还是参数,从而让参数得到应有的输出。并在在bash shell中还提供了getopt和getopts来判断是选项还是参数-------用时参考它们用法即可。
4. 获取用户输入-------交互性更强,类似java中的scanner+system.in用法
采用read命令。read后面跟变量名,就可以将输入的值保存到变量中;如果不输入变量名,那么就自动保存在了特殊环境变量REPLY中。
1 [Hermioner@localhost Documents]$ cat test1 2 #!bin/bash 3 echo -n "Enter your name:" 4 read name 5 echo "hello $name" 6 [Hermioner@localhost Documents]$ bash test1 7 Enter your name:Tom 8 hello Tom 9 [Hermioner@localhost Documents]$
note1:如果用户一直不输入,read会一直等待,因此可以设置计时器,用-t选项。时间过了,就不等了。
eg:read -t 5 name
note2: 类似密码输入,隐藏方式读取,只需要添加 -s就可以
note3: 还可以从文件中读取,一行一行的读取
1 [Hermioner@localhost Documents]$ cat test1 2 #!bin/bash 3 a 4 b 5 c 6 [Hermioner@localhost Documents]$ cat test2 7 #!/bin/bash 8 cat test1 | while read line #采用了管道 9 do 10 echo "the line is $line" 11 done 12 echo "read is done" 13 [Hermioner@localhost Documents]$ bash test2 14 the line is #!bin/bash 15 the line is a 16 the line is b 17 the line is c 18 read is done 19 [Hermioner@localhost Documents]$
补充管道:
command1 | command2 就是将命令1的输出重定向到了command2中。 可以多级重定向,多添加|就好了。
参考文献:
Linux命令行与shell脚本编程大全(第3版)[美] 布鲁姆(Richard Blum),布雷斯纳汉(Christine Bresnahan) 著,门佳,武海峰 译