##
# 本文为《shell脚本专家指南》一书的学习笔记。
##
1.1. shell跟踪
使用set -x和set -v。仅在当前脚本生效。
set -x # 打开代码跟踪。个人理解为,显示当前执行的代码。
set +x # 关闭代码跟踪。
set -v # 打开代码冗余。个人理解为,显示当前走过的代码(不一定执行)。
set +v # 关闭代码冗余。
关于set -x 和 set -v的差异,建议手动执行一遍,慢慢去体会。
可以直接set -xv 来同时启用两种追踪方式。
#!/bin/bash
set -x
set -v
# set -xv
echo -n "Can you write device drivers? Input your answer : "
read answer
answer=`echo $answer | tr [a-z] [A-Z]`
if [ $answer = Y ]; then
echo "Wow, you must be very skilled."
else
echo "Neither can I, I'm just an example shell script."
fi
1.2. 关键位置输出
在关键位置输出,使用echo 和print 命令。
#!/bin/bash
echo -n "Can you write device drivers? Input your answer : "
read answer
answer=`echo $answer | tr [a-z] [A-Z]`
if [ $answer = Y ]; then
echo "Wow, you must be very skilled."
# this is the trace.
echo "# answer : $answer"
else
echo "Neither than I, im just an example script."
# this is the trace.
echo "# answer : $answer"
fi
1.3. 使用调试层级
可以认为是'1.2关键位置输出'方法的扩展,通过DEBUG变量,来控制是否输出日志。
#!/bin/bash
# 0 is no debug, 1 is on debug。
DEBUG=1echo -n "Can you write device drivers? Input your answer : "
read answer
answer=`echo $answer | tr [a-z] [A-Z]`
if [ $answer = Y ]; then
echo "Wow, you must be very skilled."
test $DEBUG = 1 && echo "# answer : $answer"
else
echo "Neither than I, im just an example script."
test $DEBUG = 1 && echo "# answer : $answer"
fi
另一种优化的方式,是通过DEBUG变量,来实现不同的调试层级。
#!/bin/bash
# 0 is no debug, 1 or more is different debug level。
DEBUG=0
echo -n "Can you write device drivers? Input your answer : "
read answer
test $DEBUG -ge 2 && echo "# raw_answer : $answer"
answer=`echo $answer | tr [a-z] [A-Z]`
if [ $answer = Y ]; then
echo "Wow, you must be very skilled."
test $DEBUG -ge 1 && echo "# answer : $answer"
test $DEBUG -ge 2 && echo "## the man is very skilled."
else
echo "Neither than I, im just an example script."
test $DEBUG -ge 1 && echo "# answer : $answer"
test $DEBUG -ge 2 && echo "## I cannot write driver either."
fi
1.4. 使用函数
使用特定函数,判断指定脚本的返回值,如果不为0,则输出告警信息。
示例:编写alert函数 alert.sh
#!/bin/bash
alert() {
# Usage : alert <$?> <object>
if [ $1 -ne 0 ]; then
echo "WARN $2 did not complete successfully." >&2
exit $1
else
echo "INFO $2 complete successflly." >&2
fi
}
#!/bin/bash
# export alert() function.
. ./alert.sh
# export DEBUG level.
DEBUG=1
echo -n "file to read : "
read file
cat $file
alert $? "read file $file"
echo "do sth"
示例:alert的高级形式,未定义DEBUG或未开启DEBUG时,函数不执行。
如果开启了DEBUG,当上个脚本返回值不为0时,则打印报错信息。
如果DEBUG等级大于9,则脚本直接退出。
#!/bin/bash
alert() {
local RETURN_CODE=$?
if [ -z $DEBUG ] || [ $DEBUG -eq 0 ]; then
return
fi
if [ $RETURN_CODE -ne 0 ]; then
echo "WARN $* failed with return code of $RETURN_CODE ." >&2
[ $DEBUG -gt 9 ] && exit $RETURN_CODE
fi
}
1.5. 步进
通过变量 STEP_THROUGH 来控制脚本的步进执行。
示例:STEP_THROUGH 为1时,脚本会在指定位置暂停等待输入后继续。
#!/bin/bash
STEP_THROUGH=1
echo "I'm ready to start."
echo "Running step 1..."
test $STEP_THROUGH = 1 && {
echo -n "# Press [ENTER] to continue..."; read x
}
echo "Running step 2..."
test $STEP_THROUGH = 1 && {
echo -n "# Press [ENTER] to continue..."; read x
}
echo "Running step 3..."
echo "job's down"
示例:步进与alert结合,并增加步进层级。
当步进为1时,遇到警告会暂停,当步进为2时,每次调用alert都会暂停。
#!/bin/bash
alert() {
local RETURN_CODE=$?
if [ -z $DEBUG ] || [ $DEBUG -eq 0 ]; then
return
fi
if [ $RETURN_CODE -ne 0 ]; then
echo "WARN $* failed with return code of $RETURN_CODE ." >&2
[ $DEBUG -gt 9 ] && exit $RETURN_CODE
test $STEP_THROUGH = 1 && {
echo -n "# Press [ENTER] to continue..."; read x
}
fi
test $STEP_THROUGH = 2 && {
echo -n "# Press [ENTER] to continue..."; read x
}
}
#!/bin/bash
# export alert() function.
. ./alert.sh
# export DEBUG level.
DEBUG=1
# export STEP_THROUGH level.
STEP_THROUGH=1
echo -n "file to read : "
read file
cat $file
alert "read file $file"
echo "do sth"