之前已经知道,可以将一段程序写入文件然后在运行文件。
但是这样只能运行固定的代码,其实还可以向这段程序中输入参数使其更具有灵活性

和执行其它shell程序一样,只要在命令后紧跟参数即可。 shell会自动将第一个参数存储在一个特殊的变量1中,第二个变量存储在变量2中。
所以在程序中使用使用$1, $2代替参数应该出现的地方即可
这被称之为positional parameters,因为参数是由其所在的位置决定的

The $# Variable

特殊变量$#用于存储在命令行中输入的参数个数。通常用来校验用户数据的参数个数是否正确

$ cat args                  # Look at the program
echo $# arguments passed
echo arg 1 = :$1: arg 2 = :$2: arg 3 = :$3:
$ args a b c                # Execute it
3 arguments passed
arg 1 = :a: arg 2 = :b: arg 3 = :c:
$ args a b                  # Try it with two arguments
2 arguments passed
arg 1 = :a: arg 2 = :b: arg 3 = :: # Unassigned args are null
$ args                      # Try it with no arguments
0 arguments passed
arg 1 =:: arg 2 =:: arg 3 = ::
$ args "a b c"              # Try quotes
1 arguments passed
arg 1 = :a b c: arg 2 = :: arg 3 = ::
$ ls x*                     # See what files start with x
xact
xtra
$ args x*                   # Try filename substitution
2 arguments passed
arg 1 = :xact: arg 2 = :xtra: arg 3 = ::
$ my_bin=/users/steve/bin
$ args $my_bin              # And variable substitution
1 arguments passed
arg 1 = :/users/steve/bin: arg 2 = :: arg 3 = ::
$ args $(cat names)         # Pass the contents of names
7 arguments passed
arg 1 = :Charlie: arg 2 = :Emanuel: arg3 = :Fred:

The $* Variable

特殊变量$*存储了所有的传递参数

$ cat args2
echo $# arguments passed
echo they are :$*:
$ args2 a b c
3 arguments passed
they are :a b c:
$ args2 one            two
2 arguments passed
they are :one two:
$ args2
0 arguments passed
they are ::
$ args2 *
8 arguments passed
they are :args args2 names nu phonebook stat xact xtra:

A Program to Look Up Someone in the Phone Book

现有文件phonebook如下

cat phonebook
# Alice Chebba 973-555-2015
# Barbara Swingle 201-555-9257
# Liz Stachiw 212-555-2298
# Susan Goldberg 201-555-7776
# Susan Topple 212-555-4932
# Tony Iannino 973-555-1295

如果想查询某人的号码可以使用grep name phonebook的命令, 如果想输入全名则需要在需要给人名加上引号""
grep "name" phonebook

我们可以写一个lu程序,接受人名作为参数来查询

cat lu
# grep $1 phonebook
lu Alice
# Alice Chebba 973-555-2015
lu "Susan T"
# grep: T: No such file or directory
# phonebook:Susan Goldberg 201-555-7776
# phonebook:Susan Topple 212-555-4932

可以发现在查询Susan T时出错
这是因为算Susan T被当作一个参数传递给了$1,但是在执行grep命令时变量名被值替代

grep Susan T phonebook

所以应该为$1也加上双引号(注意不能使用单引号)

cat lu
# grep "$1" phonebook

A Program to Add Someone to the Phone Book

cat add
# echo "$1  $2" phonebook
# sort -u -o phonebook phonebook

A Program to Remove Someone from the Phone Book

cat rem
# grep -v "$1" phonebook > /tmp/phonebook   # 方法1
# sed "/$1/d" phonebook > /tmp/phonebook    # 方法2
# mv /tmp/phonebook phonebook

${n}

如果传递的参数超过9个,想获取地10个参数不能直接使用$10
而应该使用${10}

The shift Command

shift命令会使位置参数集体左移,即$2的值赋值给$1$3的值赋值给$2,以此类推。 而$1中的值则会被丢弃

cat tshift
# echo $# $*
# shift
# echo $# $*
# shift
# echo $# $*
# shift
# echo $# $*
# shift
# echo $# $*
# shift
# echo $# $*
tshift a b c d e
# 5 a b c d e
# 4 b c d e
# 3 c d e
# 2 d e
# 1 e
# 0

如果当$#为0时去执行shift则会报错

如果想连续多次执行shift可以直接在shift后跟数字

shift 3

等价于

shift
shift
shift