Linux之处理用户输入(二)

mark

特殊参数变量

bash shell中有些特殊变量,它们会记录命令行参数

参数统计

特殊变量$#含有脚本运行时携带的命令行参数的个数,可以在脚本中任何地方使用这个特殊变量,就跟普通变量一样

$ cat test9.sh
#!/bin/bash
# Testing parameters
#
if [ $# -ne 2 ]
then
echo
echo Usage: test9.sh a b
echo
else
total=$[ $1 + $2 ]
echo
echo The total is $total
echo
fi
#
$
$ bash test9.sh
Usage: test9.sh a b
$ bash test9.sh 10
Usage: test9.sh a b
$ bash test9.sh 10 15
The total is 25

如何获取最后一个命令行参数变量?可以通过以下方法获取:

$ cat test10.sh
#!/bin/bash
# Grabbing the last parameter
#
params=$#
echo
echo The last parameter is $params
echo The last parameter is $\{!#\}
echo
#
$
$ bash test10.sh 1 2 3 4 5
The last parameter is 5
The last parameter is 5

抓取所有数据

$*$@变量可以用来轻松访问所有参数,这两个变量能够在单个变量中存储所有的命令行参数。

  • $*变量会将命令行上提供的所有参数当作一个单词保存,这个单词包含了命令行中出现的每一个参数,基本上$*变量会将这些参数视为一个整体,而不是多个个体
  • $@变量会将命令行上提供的所有参数当作同一字符串中的多个独立的单词,这样可以遍历所有的参数值,得到每个参数
$ cat test11.sh
#!/bin/bash
# testing $* and $@
#
echo
echo "Using the $* method: $*"
echo
echo "Using the $@ method: $@"
$
$ ./test11.sh rich barbara katie jessica
Using the $* method: rich barbara katie jessica
Using the $@ method: rich barbara katie jessica

二者的差异主要如下:

$ cat test12.sh
#!/bin/bash
# testing $* and $@
#
echo
count=1
#
for param in "$*"
do
echo "$* Parameter #$count = $param"
count=$[ $count + 1 ]
done
#
echo
count=1
#
for param in "$@"
do
echo "$@ Parameter #$count = $param"
count=$[ $count + 1 ]
done
$
$ ./test12.sh rich barbara katie jessica
$* Parameter #1 = rich barbara katie jessica
$@ Parameter #1 = rich
$@ Parameter #2 = barbara
$@ Parameter #3 = katie
$@ Parameter #4 = jessica

$*变量将所有参数当成单个参数,$@变量会单独处理每个参数

移动变量

bash shellshift命令默认条件下会将每个参数变量向左移动一个位置,即变量$3的值会移到$2,以此类推,变量$1的值会被删除,变量$0的值即程序名不会改变

$ cat test13.sh
#!/bin/bash
# demonstrating the shift command
echo
count=1
while [ -n "$1" ]
do
echo "Parameter #$count = $1"
count=$[ $count + 1 ]
shift
done
$
$ ./test13.sh rich barbara katie jessica
Parameter #1 = rich
Parameter #2 = barbara
Parameter #3 = katie
Parameter #4 = jessica

处理选项

选项是跟在单破折号-后面的单个字母,比如-n,它能改变命令的行为。

查找选项

命令行选项在命令行上紧跟在脚本名之后,就跟命令行参数一样

处理简单选项

$ cat test15.sh
#!/bin/bash
# extracting command line options as parameters
#
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
$
$ ./test15.sh -a -b -c -d
Found the -a option
Found the -b option
Found the -c option
-d is not an option
#
#
$ ./test15.sh -d -c -a
-d is not an option
Found the -c option
Found the -a option

分离参数和选项

Linux处理同时含有选项和参数的情况时,利用特殊字符将两者分开,该字符会告诉脚本何时选项结束以及普通参数何时开始。这个特殊字符就是双破折线--shell会用双破折线来表明选项列表结束,在双破折线之后,脚本就可以放心将剩下的命令行参数当作参数而不是选项来处理。

$ cat test16.sh
#!/bin/bash
# extracting options and parameters
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
#
count=1
for param in $@
do
echo "Parameter #$count: $param"
count=$[ $count + 1 ]
done

在遇到双破折线时脚本用break命令跳出while循环,由于过早跳出循环,需要再加一条shift命令来将双破折线移出参数变量。

$ ./test16.sh -c -a -b test1 test2 test3
Found the -c option
Found the -a option
Found the -b option
test1 is not an option
test2 is not an option
test3 is not an option

结果说明在处理时脚本认为所有的命令行参数都是选项,下面用双破折线将命令行上的参数和选项分隔开

$ ./test16.sh -c -a -b -- test1 test2 test3
Found the -c option
Found the -a option
Found the -b option
Parameter #1: test1
Parameter #2: test2
Parameter #3: test3

当脚本遇到双破折线时它会停止处理选项,并将剩下的参数都当作命令行参数。

处理带值的选项

有些选项会带有一个额外的参数值,比如:

$ ./testing.sh -a test1 -b -c -d test2

当命令行选项要求有额外的参数时,处理如下:

$ cat test17.sh
#!/bin/bash
# extracting command line options and values
echo
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
for param in "$@"
do
echo "Parameter #$count: $param"
count=$[ $count + 1 ]
done
$
$ ./test17.sh -a -b test1 -d
Found the -a option
Found the -b option, with parameter value test1
-d is not an option

在这个例子中,case语句定义了三个处理选项,-b选项还有一个额外的参数值,由于要处理的参数是$1,额外的参数值就应该位于$2(因为所有的参数在处理完之后都会被移出)。只要将参数值从$2变量中提取出来就行了,因为这个选项占用了两个参数位,所以需要使用shift命令多移动一个位置。

Researcher

I am a PhD student of Crop Genetics and Breeding at the Zhejiang University Crop Science Lab. My research interests covers a range of issues:Population Genetics Evolution and Ecotype Divergence Analysis of Oilseed Rape, Genome-wide Association Study (GWAS) of Agronomic Traits.

comments powered by Disqus