1.1 统计参数数量
问题: 你想知道调用脚本时使用了多少个参数、
解决方案: 使用shell内建变量 $#
#!/usr/bin/env bash
# instance file : check_arg_count
#
# check out the numbers of the correct parameter
# use the grammer as below: if [ $# -lt 3 ]
if (( $# < 3))
then
printf "%b" "Error. Not enough arguments.\n" >&2
printf "%b" "usage: myscript file1 op file2\n" >&2
elif(( $# > 3))
then
printf "%b" "Error.Too many arguments.\n" >&2
printf "%b" "usage: myscript file1 op file2\n" >&2
else
printf "%b" "Argument count correct.Proceeding...\n"
fi
1.2 将输出和错误消息发送到同一文件
问题:利用重定向,我们可以将输出或错误消息保存到单独的文件中,但如何将两者送往同一文件?
解决方案: 用shell语法将标准错误消息重定向到和标准输出相同的地方。
首选
both >& outfile
或者:
both &> outfile
both 代表是准备向STDERR和STDOUT生成输出的程序。
讨论
&> 和 >& 只是 将STDOUT 和 STDERR 发送到相同地方。
both 2> outfile 1>&2
1 代表标准输出
2 代表标准错误
1.3 正确地使用logger
问题: 你想利用logger工具使脚本能够发送syslog消息,但默认情况下,logger并没有提供足够的有用信息。
解决方案:
logger -t "${0##*/}[$$]" 'Your message here'
要是没使用 logger 的 -t 选项,即便算不上致命错 误,起码也得接受警告。t 代表“标签”(tag),按照手册页中所 言,它会“使用指定的标签来标记所记录的每一行内容”。换句话 说,要是没有 -t 选项,你很难知道这些日志消息都是从哪来的。
${0##*/}[$$] 标签可能看起来像乱码,但查看 syslog 日志记录 时经常会看到它。该标签只不过就是脚本的基本名称和位于方括号内 的进程 ID($$)而已。比较一下使用和不使用 -t 选项的 logger。
1.4 typeset
typeset 声明变量并赋予属性,等同于declare
1.5 了解命令是否成功运行
问题: 你需要知道命令是否成功运行
解决方案:编写命令或shell脚本的程序员遵循既定约定,那么shell变量$? 会在命令失败时被设置为非0值。
$ somecommand
# it works...
$ echo $?
0
$ badcommand
# it fails...
$ echo $?
1
$
讨论: shell变量 $? 中保存着命令的退出状态,其取值范围为0·255
在编写 shell 脚本时,良好的做法是:如果一切正常,脚本退出时就 返回 0;如果运行过程中出错,则返回非 0 值。我们推荐只使用 0~127 作为返回值,因为 shell 用 128+N 代表被信号 N“杀 死”。另外,如果使用的值大于 255 或小于 0,则会出现值回绕。 可以用 exit 语句(如 exit 1 或 exit 0)返回退出状态。但要 注意,读取命令退出状态的机会只有一次
但是 $? 这种变量的真正用途是 在脚本编写方面。如果在屏幕上观看命令运行,通常可以看出该命令 是否正常。但在脚本中,命令运行时也许无人值守。
bash 的一大特点是,脚本语言与在终端窗口提示符下键入的命令完全 相同。在编写脚本时,这使得检查语法和逻辑要容易得多。
退出状态多用于脚本和 if 语句中,根据所执行命令的成功与否采取 不同的处理方式。下面这个示例比较简单,但我们后续还会讨论这个 话题。
somecommand
...
if (( $? )) ; then echo failed ; else echo OK; fi
(( )) 对算术表达式进行求值
我们不推荐使用负数。shell 可以接受负数,也不会报错,但结果并 不如你所愿。
$ bash -c 'exit -2' ; echo $?
254
$ bash -c 'exit -200' ; echo $?
56