#shell 输入输出
1. 命令行参数输入
在shell脚本中可以使用$n
来引用命令行中指定的参数。$0
是脚本名字,$1
是第一个参数,$2
是第二个…以此类推直到$9
。命令来行上指定的参数以空格隔开,如果需要包含空格的参数,要用引号扩起来。如果需要指定的参数不止九个,之后的变量的数字要用大括号扩起来,比如${10}
。
在使用命令行参数之前,需要检查参数是否被赋值。
特殊参数变量
$#
含有脚本运行时携带的参数的个数(不包括脚本名)。
$*
会将所有的命令行参数当作一个单词保存,而不是多个单词。
$@
会将所有的命令行参数当作一个办含多个单词的列表。
移动变量
shift
命令会将命令行参数的位置左移一位。$1
的内容删除,$2
的值给$1
,$3
的值给$2
…$0
仍然是程序名。使用shift
要注意,移除的参数无法恢复。shift n
可以一次移动多位。
处理选项
选项的指定没有特定的顺序,有的选项可以接参数,没有参数的选项可以连在一起。
getopt
命令可以接受一系列任意形式的命令行选项和参数,并自动将他们转换成适当的格式。
getopt <optstring> <parameters>
optstring
定义了命令行中有效的选项字母和哪些选项需要参数值。首先,在optstring
中列出你要在脚本中用到的选项字母,在每个需要参数的选项字母后加上冒号。
➜ getopt ab:cd -a -b arg -cd args
-a -b arg -c -d -- args
getopt
将选项参数规范化,并用双破折线分隔额外的参数。如果指定了一个不再optstring
中的选项,默认会产生一个错误信息。并输出能识别的部分。在getopt
后面加上-q
选项可以屏蔽此错误信息。
➜ getopt ab:cd -a -b arg -cde args
getopt: invalid option -- 'e'
-a -b arg -c -d -- args
处理命令行参数的标准示例:
➜ shell_scripts git:(dev) ✗ cat deal_with_args.sh
#! /bin/bash
# Extract command line options and value with getopt
set -- $(getopt -q ab:cd "$@")
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
➜ shell_scripts git:(dev) ✗ bash deal_with_args.sh -a -b test1 -cd test2 test3 test4
Found the -a option
Found the -b option, with parameter value 'test1'
Found the -c option
-d is not an option
Parameter #1: 'test2'
Parameter #2: 'test3'
Parameter #3: 'test4'
getopts
命令与getopt
不同,每次调用它,只处理命令行上检测到的一个参数。处理完所有参数后,它会退出并返回一个大于0
的退出状态码。
getopts <optstring> <variable>
optstring
类似于getopt
中的那个。如果要去掉错误消息,可以在optstring
的首部加一个冒号。getopts
命令会用到两个环境变量。如果选项需要参数值,OPTARG
环境变量会保存这个值。OPTIND
保存了参数列表中getopts
正在处理的参数位置。variable
保存着当前处理的选项。
示例:
➜ shell_scripts git:(dev) ✗ cat getopts.sh
#! /bin/bash
# simple demonstration of the getopts command
echo
while getopts :ab:c opt
do
case "$opt" in
a) echo "Found -a option";;
b) echo "Found -b option, with value $OPTARG";;
c) echo "Found -c option";;
*) echo "Unknow option: $opt";;
esac
done
➜ shell_scripts git:(dev) ✗ bash getopts.sh -ab test1 -c
Found -a option
Found -b option, with value test1
Found -c option
2. 用read读取输入
read
将输入信息读入到一个或者多个shell变量中。
语法:
read [ -r ] variable...
-p msg
: 输出提示字符串msg
后,等待输入-t secs
: 设置超时定时器。超时后,read
返回非零退出码。-s
: 不回显输入的内容
从标准输入读取行数据后,通过shell字段切割的功能(使用$IFS
)进行切分。第一个单词赋值给第一个变量,第二个单词赋值给第二个变量,以此类推。如果单词多于变量,则剩下的单词,全赋值给最后一个变量。read
一旦遇到文件结尾(eof
),会以失败退出
如果输入行以反斜杠结尾,则丢弃反斜杠和换行,继续读取下一行数据。如果使用了-r
选项,则会以字面值解释反斜杠。
如果要从文件中读取数据,可以使用cat text | read
或者重定向read ... < text
。
3. echo 输出
- 原始的
echo
命令只会将参数打印到标准输出,参数之间用一个空格隔开,并以换行符结尾。 echo
命令的选项必须放在输出字段前面,否则会被作为输出内容。- 注意
echo
的参数是多个分立的单词,而不是一个整体的句子。 要想输出某具体字符串,需要把它加上引号(单引号或者双引号)。 - 如果不想自动输出换行,第一个参数使用
-n
。字符串中可以包含转义字符,比如\n
,\t
等。 - 要打印彩色文本,可输入如下命令:
echo -e "\e[1;31m This is red text \e[0m"
。\e[1;31
将颜色设为红色,\e[0m
将颜色重新置回。只需要将31替换成想要的颜色码就可以了。要设置彩色背景,经常使用的颜色码是:重置=0,黑色=40,红色=41,绿色=42,黄色=43,蓝色=44,洋红=45,青色=46,白色=47。 - 使用单引号时,变量不会被扩展,将依照原样显示。
- 如果需要输出
!
,不要直接把它放到""
中,要加\
转义;或者用''
。 - 更多细节参考
man echo
4. printf 输出
echo
在不同系统间有不同的版本,可移植性较差,一般只使用echo
的简单形式。如果需要复杂具体的输出,使用printf
会更恰当。
printf
format-string [arguments ...]
printf
命令的完整语法分为两部分:第一部分是一个字符串,用来描述输出的排列方式,最好为此字符串加上引号。此字符串包含了字面显示的字符以及格式声明。格式声明又叫占位符,用来描述如何显示相应的参数。
第二部分是与格式声明相对应的参数列表。格式声明分成两部分:百分比符号(%)和指示符,这些都跟C语言的printf函数类似。
如果参数的个数比格式声明要多,那么printf会循环且依次地使用字符串输出,直至处理完参数。
$ printf "hello %c\n" a b c
hello a
hello b
hello c
$ printf "hello %c %c\n" a b c
hello a b
hello c
$