命令行参数

  • 命令行参数:允许在运行脚本时向命令行添加数据值

$ ./addem 10 30

读取参数

  • bash shell会将一些称为位置参数的特殊变量分配给命令行输入的所有参数,甚至包括shell执行的程序的名字
  • 位置参数变量是标准的数字
  • $0:程序名
  • $1:第一个参数
  • 2:第二个参数,以此类推,直到第9个参数9

$cat test

           #!/bin/bash

total=$[ $1 * $2 ]

$total.

$./test 2 5

The total value is 10.

  • shell参数可以是字符串,每个参数都是用空格分隔的,所以shell会将空格当成分隔两个值的分隔符
  • 参数值中包含空格,必须要用引号(单引号双引号都可以)

 

 

#cat test
#!/bin/bash
 
echoHello$1,glad tomeet you
$./test'Rich Blum'
Hello Rich Blum,glad tomeet you.
$
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

 

  • 脚本需要多于9个命令行参数时,需要使用花括号{},比如,${10}

读取程序名

  • $0:获取shell在命令行启动的程序的名字
  • 当传给$0变量的真实字符串是整个脚本的路径时,程序中就会使用整个路径,而不仅仅是程序名
  • basename命令会只返回程序名而不包括路径

 

 

$cattest
#!/bin/bash
name=`basename$0`
echoThe commandentered is:$0
echoThe commandentered is:$name
$./test
The commandentered is:./test
The commandentered is:test
$/home/rich/test
The commandentered is:/home/rich/test
The commandentered is:test
$
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

 

测试参数

  • 当脚本认为参数变量中有数据而实际上并没有时,会得到一个错误
  • 解决方法:在使用参数前检查参数[ -n “$1” ]

特殊参数变量

参数计数

  • $#特殊变量:含有脚本运行时就有的命令行参数的个数,可以在脚本中任何地方使用,跟普通变量一样
  • 最后一个参数的表示形式是{!#}而不是{$#}
  • 当命令行上没有任何参数时,#的值为0,在params变量中也为0,但{!#}变量返回命令行用到的脚本名

 

$cattest
#!/bin/bash
 
if[$# -ne 2 ]
then
echoUsage:testab
else
total=$[$1+$2]
echoThe total is$total
fi
$./test
Usage:testab
$./test10
Usage:testab
$./test1015
The total is25
$./test101520
Usage:testab
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

 

 

抓取所有的数据

  • ∗和@变量提供了对所有参数的快速访问,这两个都能在单个变量中存储所有的命令行参数
  • $*:会将命令行上提供的所有参数当做单个单词保存,即当成一个参数
  • $@:将命令行上提供的所有参数当做同一字符串中的多个独立的单词,允许遍历所有的值,将提供的每个参数分隔开来,通常用for命令完成

 移动变量

  • shift命令:根据它们的相对位置来移动命令行参数
  • 默认情况下会将每个参数变量减1,所以变量3的值会移动到2,2的值会移动到1,而变量$1的值会被删除
  • shift命令可以提供一个参数n来执行多位移动,如shift 2:连续移动2位
  • 当一个参数被移除后,它的值会被丢掉无法恢复
  • 变量$0的值,也就是程序名不会改变
  • 可以用shift命令遍历命令行参数,尤其在不知道到底有多少个参数的时候

 

 

$cattest
#!/bin/bash
 
count=1
while[-n"$1"]
do
echo"Parameter #$count = $1"
count=$[$count+1]
shift
done
$
$./testrich barbara
parameter#1 = rich
Parameter#2 = barbara
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

 

处理选项

  • 选项:跟在单破折线后面的单个字母,能改变命令的行为(如: ls -a)

 查找选项

  • 在命令行上,选项紧跟在脚本名之后,就跟命令行参数一样
  • 处理简单选项:在提取参数时,用case语句来判断参数是否被格式化成了选项

 

$cattest
#!/bin/bash
 
while[-n"$1"]
do
case"$1"in
-a)echo"Found the -a option";;
-b)echo"Found the -b option";;
*)echo"$1 is not an option";;
esac
shift
done
$
$./test-a-c
Found the-aoption
-cisnotan option
$
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

 

 

  • 分离参数和选项
  • shell会用双破折线来表明选项结束了,遇到双破折线之后,脚本会安全地将剩下的命令行参数当做参数来处理,而不是选项

 

$cattest
#!/bin/bash
 
while[-n"$1"]
do
case"$1"in
-a)echo"Found the -a option";;
-b)echo"Found the -b option";;
--)shift
break;;
*)echo"$1 is not an option";;
esac
shift
done
 
count=1
forparam in$@
do
echo"Parameter #$count: $param"
count=$[$count+1]
done
$
$./test-atest1
Found the-aoption
test1 isnotan option
$./test-a--test1
Found the-aoption
Parameter#1: test1
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

 

 

  • 处理带值的选项
  • 当命令行选项要求额外的参数时,脚本必须能检测并能正确的处理

 

$cattest
#!/bin/bash
 
while[-n"$1"]
do
case"$1"in
-a)echo"Found the -a option";;
-b)param="$2"
echo"Found the -b option, with parameter value $param"
shift2;;
-c)echo"Found the -c option";;
--)shift
break;;
*)echo"$1 is not an option";;
esac
shift
done
 
count=1
forparam in"$@"
do
echo"Parameter #$count: $param"
count=$[$count+1]
done
$
$./test-a-btest1-d
Found the-aoption
Found the-boption,with parameter value test1
-disnotan option
$
$./test-btest1-a-d
Found the-boption,with parameter value test1
Found the-aoption
-disnotan option
$
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.

 

 

  • 如果将多个选项放进一个参数中时,它就不工作了

 

$./test-ac
-<span class="ruby">ac is<span class="hljs-keyword">not</span>an option
</span>$
  • 1.
  • 2.
  • 3.

 

 

使用getopt命令

  • getopt:识别命令行,从而在脚本中解析它们时更方便
  • 命令格式:getopt options optstring parameters
  • optstring:定义了命令行有效的选项字母,还定义了哪些选项字母需要参数值
  • 首先,在optstring中列出你要在脚本中用到的每个命令行选项字母
  • 然后,在每个需要参数值的选项字母后加一个冒号
  • getopt命令会给予你定义的optstring解析提供的参数

 

 

$getoptab:cd-a-btest1-cdtest2 test3
-a-btest1-c-d--test2 test3
$
  • 1.
  • 2.
  • 3.

 

  • 如果指定了一个不在optstring中的选项,默认情况下,getopt命令会产生一条错误信息
  • 如果想忽略这条错误,在命令后加上-q选项

 

$getoptab:cd-a-btest1-cde test2 test3
getopt:invail option--e
-a-btest1-c-d--test2 test3
$
$getopt-qab:cd-a-btest1-cde test2 test3
-a-btest1-c-d--test2 test3
$
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

 

 

  • 在脚本中使用getopts
  • 可以在脚本中使用getopt来格式化输入给脚本的任何命令行选项
  • 方法:
  • 首先,用getopt命令生成的格式化后的版本来替换已有的命令行选项和参数,用set命令可以做到
  • set命令的选项之一是双破折号,它会将命令行参数替换成set命令的命令行的值
  • 然后,该方法将原始的脚本命令行参数传递给getopt命令
  • 之后再将getopt命令的输出传给set命令,用getopt格式化后的命令行参数来替换原始的命令行参数
  • 看起来如下:

set — getopts -q ab:cd "$@"

 


 

Shell

 

$cattest
#!/bin/bash
 
set--`getopt-qab:c"$@"`
while[-n"$1"]
do
case"$1"in
-a)echo"Found the -a option";;
-b)param="$2"
echo"Found the -b option, with parameter value $param"
shift;;
-c)echo"Found the -c option";;
--)shift
break;;
*)echo"$1 is not an option";;
esac
shift
done
 
count=1
forparam in"$@"
do
echo"Parameter #$count: $param"
count=$[$count+1]
done
$
$./test-a-btest1-cdtest2 test3
Found the-aoption
Found the-boption,with parameter value'test1'
Found the-coption
Parameter#1: 'test2'
Parameter#1: 'test3'
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.