命令行参数
读取参数
- 位置参数:
$0
是程序名,$1
是第一个参数,$2
是第二个参数,以此类推直到第9个参数。 - 每个参数都是用空格分隔的,所以shell会将空格当成两个值的分隔符
- 要在参数值中包含空格,必须要用引号(单引号或双引号都可以,当然引号并非数据的一部分,它们只是表明数据的起止位置)
- 如果命令行参数不止9个,必须在变量数字周围加上花括号,比如
${10}
读取脚本名 $0
:如果使用另一个命令来运行shell脚本,命令会和脚本名混在一起出现在$0
中,使用完整的脚本路径时$0
也会用整个路径basename
命令可以返回不包含路径的脚本名
测试参数
使用参数前一定要检查其中是否存在数据,可以使用-n
测试来检查命令行参数$1
中是否有数据
特殊参数变量
参数统计:$#
为含有脚本运行时携带的命令行参数的个数
抓取所有的数据:
$*
:将命令行上提供的所有参数当作一个单词保存$@
:将命令行上提供的所有参数当作同一个字符串中的多个独立的单词(通过空格分隔吗)
移动变量
shift
命令会根据参数的相对位置来移动命令行参数,默认情况下它会将每个参数变量向左移动一个位置,$3
会移动到$2
, $2
会移动到$1
,而变量$1
的值会被删除($0
的值是程序名,不会改变)。这是遍历命令行的一个好方法,尤其是在不知道有多少参数的情况下。
echo
count=1
while [ -n "$1" ]; do
echo "Parameter #$count=$1"
count=$[ $count + 1 ]
shift
done
使用shift
要注意,如果某个参数被移出,它的值就被丢弃了,无法再恢复。
另外,可以一次性移动多个位置,只需要给shift
命令提供一个参数,指明要移动的位置数
处理选项
处理简单选项
选项和参数不同,选项是跟在单破折号后面的单个字母,它能改变命令的行为。在提取单个参数时,可以用case
语句来判断某个参数是否为选项
echo
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";;
*) echo "$1 is not an option";;
esac
shift
done
分离参数和选项
会经常遇到在shell脚本中同时使用选项和参数的情况,linux中处理这个问题的标准方式是用特殊字符(双破折线–)将二者分开,该字符会告诉脚本何时选项结束以及普通参数何时开始。当脚本遇到双破折线时,表明选项列表结束
echo
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
处理带值的选项
echo
while [ -n "$1" ]; do
case "$1" in
-a) echo "Found the -a option";;
-b) param=$2
echo "Found the -b option, param is $param"
shift ;;
-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=$[ $count+1 ]
done
使用getopt命令
getopt
命令是一个处理命令行选项和参数时非常方便的工具,能够识别命令行参数
将选项标准化
获得用户输入
基本读取
read
命令从标准输入或另一个文件描述符中接受输入,在收到输入后read
命令会将数据放进一个变量
echo -n "Enter your name"
read name
echo "Hello, $name, welcome to my program."
read -p "Please enter your age: " age
days=$[ $age*365 ]
echo "That makes you over $days days old! "
注意:
echo
命令使用了-n
,该选项不会在字符串末尾输出换行符read -p
:允许直接在read
命令行指定提示符- 也可以在read命令行中不指定变量,如果是这样
read
命令会将它接收到的任何数据放进特殊的环境变量REPLY
中
超时
使用read
命令的-t
选项来指定一个计时器。-t
指定了read
命令等待输入的秒数,当计时器过期后,read
命令会返回一个非零退出状态码
read -p -t 5 "Please enter your age: " age
隐藏和从文件中读取
以隐藏的方式读取:read -s
避免在read命令中输入的数据出现在显示器上
从文件中读取,当文件中没有内容时read命令会退出并返回非零退出状态码。最难的部分是将文件中的数据传给read
命令。最常见的方法是对文件使用cat命令,将结果通过管道直接传给含有read
命令的while
命令
count=1
cat aaa.txt | while read line
do
echo "Line $count: $line"
count=$[ $count+1 ]
done