标签:please 数位 检查 reply 数列 break val 指定 amt
命令行参数
向shell脚本传数据的最基本方法是使用命令行参数,命令行参数允许在运行脚本时向命令行添加数据值
读取参数
bash shell会将一些称为位置参数的特殊变量分配给命令行输入的所有参数,甚至包括shell执行的程序的名字,$0是程序名,$1是第一个参数,$2是第二个参数
代码4-1
root@lejian:/data# cat demo1
#!/bin/bash
factorial=1
for ((i=1;i<=$1;i++))
do
factorial=$[ $factorial * $i ]
done
echo "The factorial of $1 is $factorial"
root@lejian:/data# ./demo1 5
The factorial of 5 is 120
输入更多的命令项用空格分开
代码4-2
root@lejian:/data# cat demo2 #!/bin/bash sum=$[ $1 + $2 ] echo "The first parameter is $1" echo "The second parameter is $2" echo "The sum is $sum" root@lejian:/data# ./demo2 3 5 The first parameter is 3 The second parameter is 5 The sum is 8
当输入为字符串时如果存在空格,必须使用单引号或双引号
代码4-3
root@lejian:/data# cat demo3 #!/bin/bash echo "Hello $1,glad to meet you" echo "Hello $2,glad to meet you" root@lejian:/data# ./demo3 John "Rich blum" Hello John,glad to meet you Hello Rich blum,glad to meet you
如果脚本需要多于9哥命令行参数,需要在数字周围加上花括号如:${10}、${11}
代码4-4
root@lejian:/data# cat demo4
#!/bin/bash
sum=$[ $10 + $11 ]
echo "The tenth paramter is ${10}"
echo "The eleventh paramter is ${11}"
echo "The sum is $sum"
root@lejian:/data# ./demo4 1 2 3 4 5 6 7 8 9 10 11
The tenth paramter is 10
The eleventh paramter is 11
The sum is 21
当传给$0变量的真实字符串是整个脚本的路径时,程序中就会使用整个路径,而不仅仅是程序名
代码4-5
root@lejian:/data# cat demo5 #!/bin/bash echo "The command entered is : $0" root@lejian:/data# /data/demo5 The command entered is : /data/demo5 root@lejian:/data# ./demo5 The command entered is : ./demo5
basename命令只返回程序名而不包括路径
代码4-6
root@lejian:/data# cat addem
#!/bin/bash
name=`basename $0`
if [ $name = "addem" ]
then
total=$[ $1 + $2 ]
elif [ $name = "multem" ]
then
total=$[ $1 * $2 ]
fi
echo "The total is $total"
root@lejian:/data# ./addem 2 5
The total is 7
root@lejian:/data# cp -s addem multem
root@lejian:/data# ./multem 2 5
The total is 10
可以使用-n检查命令行参数中是否有数据,如果要对命令行参数进行字符串比较最好加上双引号
代码4-7
root@lejian:/data# cat demo6
#!/bin/bash
if [ -n "$1" ]
then
echo "Hello,$1"
else
echo "Sorry, you did not identify yourself"
fi
root@lejian:/data# ./demo6 Tom
Hello,Tom
root@lejian:/data# ./demo6
Sorry, you did not identify yourself
$#特殊变量含有脚本运行时就有的命令行参数的个数
代码4-8
root@lejian:/data# cat demo1 #!/bin/bash echo "There were $# parameters supplied" root@lejian:/data# ./demo1 1 2 3 4 5 There were 5 parameters supplied root@lejian:/data# ./demo1 Tom "Hello World" There were 2 parameters supplied
代码4-9
root@lejian:/data# cat demo2
#!/bin/bash
if [ $# != 2 ]
then
echo "Usage:demo2 a b"
else
sum=$[ $1 + $2 ]
echo "The sum is $sum"
fi
root@lejian:/data# ./demo2
Usage:demo2 a b
root@lejian:/data# ./demo2 3
Usage:demo2 a b
root@lejian:/data# ./demo2 3 5
The sum is 8
root@lejian:/data# ./demo2 3 5 8
Usage:demo2 a b
注:$#虽然代表命令行参数的个数,但${$#}并不能显示最后一个命令行参数的变量
使用${!#}可以显示最后一个参数,或者将$#赋给一个变量param,然后也按特殊命令行参数变量的格式使用了该变量。但要注意的是,当命令行上没有任何参数时,$#的值为0,但${!#}变量会返回命令行用到的脚本名
代码4-10
root@lejian:/data# cat demo3
#!/bin/bash
echo "The last parameter was $#"
echo "The last parameter was ${!#}"
root@lejian:/data# ./demo3
The last parameter was 0
The last parameter was ./demo3
root@lejian:/data# ./demo3 1 2 3 4 5 6
The last parameter was 6
The last parameter was 6
$*和$@变量提供了对所有参数的快速访问,$*变量会将命令行上提供的所有参数当做单个单词保存,$@变量会将命令行上提供的所有参
数当做同一个字符串中多个独立的单词
代码4-11
root@lejian:/data# cat demo4
#!/bin/bash
count=1
for param in "$*"
do
echo "\$* Parameter #$count = $param"
((count++))
done
count=1
echo "——————————————————————"
for param in "$@"
do
echo "\$@ Parameter #$count = $param"
((count++))
done
root@lejian:/data# ./demo4 Hadoop Spring MyBatis Hibernate Shiro
$* Parameter #1 = Hadoop Spring MyBatis Hibernate Shiro
——————————————————————
$@ Parameter #1 = Hadoop
$@ Parameter #2 = Spring
$@ Parameter #3 = MyBatis
$@ Parameter #4 = Hibernate
$@ Parameter #5 = Shiro
shift命令默认情况下它会将每个参数变量的索引值减1,所以,变量$3的值会移到$2,变量$2的值会移到$1,而变量$1的值则会被删除
(变量$0的值,也就是程序名不会变),每执行一次shift命令,所有参数的位置移动一位
代码4-12
root@lejian:/data# cat demo5
#!/bin/bash
count=1
while [ -n "$1" ]
do
echo "Parameter #$count = $1"
((count++))
shift
done
root@lejian:/data# ./demo5 Hadoop Spring MyBatis Hibernate Shiro
Parameter #1 = Hadoop
Parameter #2 = Spring
Parameter #3 = MyBatis
Parameter #4 = Hibernate
Parameter #5 = Shiro
也可以给shift命令提供一个参数来执行多位移动
代码4-13
root@lejian:/data# cat demo6 #!/bin/bash echo "The original parameters : $*" shift 2 echo "Here‘s the new first parameter : $1" root@lejian:/data# ./demo6 1 2 3 4 5 6 The original parameters : 1 2 3 4 5 6 Here‘s the new first parameter : 3
处理选项,选项是跟在单破折线后面的单个字母,能改变命令的行为
shell用特殊字符(--)双破折线来表明选项结束了,将剩余命令行参数交给后续程序处理
代码4-14
root@lejian:/data# cat demo1
#!/bin/bash
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option";;
-b) echo "Found the -b option";;
-c) echo "Found the -c option";;
--) shift
break;;
*) echo "$1 is not an option";;
esac
shift
done
count=1
for param in "$@"
do
echo "Parameter #$count : $param"
((count++))
done
root@lejian:/data# ./demo1 -a -b -c test1 test2 test3
Found the -a option
Found the -b option
Found the -c option
test1 is not an option
test2 is not an option
test3 is not an option
root@lejian:/data# ./demo1 -a -b -c -- test1 test2 test3
Found the -a option
Found the -b option
Found the -c option
Parameter #1 : test1
Parameter #2 : test2
Parameter #3 : test3
getopt命令可以接受一系列任意形式的命令行选项和参数,并自动将他们转换成适当的格式
getopt optstring options parameters
optstring定义了命令行有效的选项字母,每个需要参数值的选项字母后加一个冒号
代码4-15
root@lejian:/data# getopt ab:cd -ab test1 -cd test2 test3 -a -b test1 -c -d -- test2 test3
如代码4-15所示,optstring定义了4哥有效选项字母,a、b、c和、d。它还定义了选项字母b需要一个参数值,当getopt 命令运行时,它会检查提供的参数列表,并基于optstring解析。它会自动将-cd选项分成两个单独的选项,并插入双破折线分开航中的额外参数
如代码4-16,如果置顶一个不在optstring中的选项,默认情况下,getopt 命令会产生一条错误的信息,加上-q则可以忽略这条信息:
代码4-16
root@lejian:/data# getopt ab:cd -ab test1 -cde test2 test3 getopt: invalid option -- ‘e‘ -a -b test1 -c -d -- test2 test3 root@lejian:/data# getopt -q ab:cd -ab test1 -cde test2 test3 -a -b ‘test1‘ -c -d -- ‘test2‘ ‘test3‘
set命令的选项之一是双破折线,该方法会将原始的脚本的命令行参数传给getopt命令,之后再将getopt的输出传给set命令,set会将命令行参数值替换成传递给它的值
代码4-17
root@lejian:/data# cat demo2
#!/bin/bash
set -- `getopt -q ab:c "$@"`
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option";;
-b) param="$2"
echo "Found -b option. with parameter value $param"
shift;;
-c) echo "Found the -c option";;
--) shift
break;;
*) echo "$1 is not a option"
esac
shift
done
count=1
for param in "$@"
do
echo "Parameter #$count : $param"
((count++))
done
root@lejian:/data# ./demo2 -ac
Found the -a option
Found the -c option
root@lejian:/data# ./demo2 -ab test1 -cd "test2 test3" test4 test5
Found the -a option
Found -b option. with parameter value ‘test1‘
Found the -c option
Parameter #1 : ‘test2
Parameter #2 : test3‘
Parameter #3 : ‘test4‘
Parameter #4 : ‘test5‘
从代码4-17可以看出,getopt命令并不擅长处理带空格的参数值,它会将空格当作参数分隔符,而不是根据双引号将二者当作一个参数,幸而,可以使用getopts解决这一问题
getopts在每次调用它时,只处理一个命令行上检测到的参数。处理完所有参数后,它会退出并返回一个大于0的退出状态码
getopts optstring variable
getopts 中的optstring 与之前类似,如果选项字母要求有参数值的话,就加一个冒号,如果要去掉错误信息的话,就在optstring 之前加一个冒号
getopts 命令会用到两个环境变量。如果选项需要跟一个参数值,OPTARG环境变量就会保存这个值。OPTIND环境变量保存了参数列表中getopts 正在处理的参数位置
代码4-18
root@lejian:/data# cat demo3
#!/bin/bash
while getopts :ab:c opt
do
case "$opt" in
a) echo "Found the -a option";;
b) echo "Fount the -b option, with value $OPTARG";;
c) echo "Found the -c option";;
*) echo "Unknow option : $opt ";;
esac
done
root@lejian:/data# ./demo3 -ab test1 -c
Found the -a option
Fount the -b option, with value test1
Found the -c option
root@lejian:/data# ./demo3 -b "test1 test2" -a
Fount the -b option, with value test1 test2
Found the -a option
root@lejian:/data# ./demo3 -d
Unknow option : ?
root@lejian:/data# ./demo3 -acde
Found the -a option
Found the -c option
Unknow option : ?
Unknow option : ?
root@lejian:/data# ./demo3 -abtest1
Found the -a option
Fount the -b option, with value test1
如代码4-18,getopts可以很好的处理包含空格的参数值,能够将命令行上找到的所有未定义的选项统一输出成问号,optstring 中未定义的选项字母会以问号形式发送给代码,同时可以将选项字母和参数值放一起使用而不用加空格
OPTIND和shift命令一起使用来移动参数
代码4-19
root@lejian:/data# cat demo4
#!/bin/bash
while getopts :ab:cd opt
do
case "$opt" in
a) echo "Found the -a option";;
b) echo "Fount the -b option, with value $OPTARG";;
c) echo "Found the -c option";;
d) echo "Found the -d option";;
*) echo "Unknow option : $opt ";;
esac
done
shift $[ $OPTIND - 1 ]
count=1
for param in "$@"
do
echo "Parameter $count : $param"
((count++))
done
root@lejian:/data# ./demo4 -ab test1 -d test2 test3 test4
Found the -a option
Fount the -b option, with value test1
Found the -d option
Parameter 1 : test2
Parameter 2 : test3
Parameter 3 : test
获取用户输入
read命令接受从标准输入后,会将数据放进一个标准变量
代码4-20
root@lejian:/data# cat demo5 #!/bin/bash echo -n "Enter your name:" read name echo "Hello $name, welcome to my program" root@lejian:/data# ./demo5 Enter your name:Tom Hello Tom, welcome to my program
read命令包含-p选项,允许在字符串后接收参数 ,参数与字符串必须用空格分隔
代码4-21
root@lejian:/data# cat demo1 #!/bin/bash read -p "Enter your name:" first last echo "Your name is $last. $first..." root@lejian:/data# ./demo1 Enter your name:Rich Blum Your name is Blum. Rich...
读取多个输入
代码4-22
root@lejian:/data# cat demo6 #!/bin/bash read -p "Please enter your age:" age days=$[ $age * 365 ] echo "That makes you over $days daysold" root@lejian:/data# ./demo6 Please enter your age:20 That makes you over 7300 daysold
如果read命令行中不指定变量,会将接收到的数据都存放进特殊环境变量REPLY中
代码4-23
root@lejian:/data# cat demo2
#!/bin/bash
read -p "Enter a number:"
factorial=1
for ((i=1;i<=$REPLY;i++))
do
factorial=$[ $factorial * $i ]
done
echo "The factorial of $REPLY is $factorial"
root@lejian:/data# ./demo2
Enter a number:5
The factorial of 5 is 120
代码4-24
root@lejian:/data# cat demo3 #!/bin/bash read -p "Enter your parameter:" echo "Your parameter:$REPLY" root@lejian:/data# ./demo3 Enter your parameter:6 Your parameter:6 root@lejian:/data# ./demo3 Enter your parameter:8 9 Your parameter:8 9
read命令如果没有输入就会一直等下下去,可加-t选项来指定一个计时器,当计时器过后,read会返回一个非0状态码
代码4-25
root@lejian:/data# cat demo4
#!/bin/bash
echo "time:`date "+%Y-%m-%d %H:%M:%S"`"
if read -t 5 -p "Please enter your name:" name
then
echo "Hello $name, welcome to my script time:`date "+%Y-%m-%d %H:%M:%S"` "
else
echo "Sorry, too slow! time:`date "+%Y-%m-%d %H:%M:%S"`"
fi
root@lejian:/data# ./demo4
time:2016-12-04 16:06:06
Please enter your name:Tom
Hello Tom, welcome to my script time:2016-12-04 16:06:08
root@lejian:/data# ./demo4
time:2016-12-04 16:06:12
Please enter your name:Sorry, too slow! time:2016-12-04 16:06:17
可以用read命令来对输入的字符计数,当输入的字符达到预设的字符数时,它会自动将输入的数据赋给变量并开始执行往下的程序,将-n
和1一起使用,告诉read命令在接受单个字符后退出
代码2-25
root@lejian:/data# cat demo5
#!/bin/bash
read -n1 -p "Do you want to continue [Y/N]" answer
case $answer in
Y|y) echo
echo "Fine,continue on...";;
N|n) echo
echo "OK,goodbye"
exit;;
esac
echo "This is the end of the script"
root@lejian:/data# ./demo5
Do you want to continue [Y/N]y
Fine,continue on...
This is the end of the script
隐藏方式读取,-s选项会阻止将传给read命令的数据显示在显示器上(实际数据会显示,只是read命令会将文本颜色设成跟背景色一样)
代码2-26
root@lejian:/data# cat demo6 #!/bin/bash read -s -p "Enter your password:" pass echo echo "Is your password really $pass" root@lejian:/data# ./demo6 Enter your password: Is your password really hello
将cat的结果通过管道输出给read
代码2-17
root@lejian:/data# cat text
Spring
MyBatis
Hibernate
Shiro
Hadoop
Spark
root@lejian:/data# cat demo1
#!/bin/bash
count=1
cat text | while read line
do
echo "Line $count:$line"
((count++))
done
root@lejian:/data# ./demo1
Line 1:Spring
Line 2:MyBatis
Line 3:Hibernate
Line 4:Shiro
Line 5:Hadoop
Line 6:Spark
标签:please 数位 检查 reply 数列 break val 指定 amt
原文地址:http://www.cnblogs.com/baoliyan/p/6128981.html