Shell Script Template

This is a good script template which returns JSON response, it has exit hook, logs and arguments checking. I will continuously update it if I find good patterns.

Use Python script is more developer friendly and easy to maintain.

对于一般用途的script,有几点需要注意:

  1. shebang 必须有 #!/usr/bin/env bash or #!/usr/bin/env sh
  2. debug set 放开头, 如同这里一样
  3. usage 函数格式要清晰,可以参考这个例子,且必须有-h/--help flag
  4. 传入的argument 要检查个数,以及是否为空
  5. 参数输入多多测试不同情况
  6. 可能需要log,可用temp 以及 exit hook解决,log放 /tmp directory
  7. 输出信息用[date time] prefix, 可以用LogMsg function wrap一下

Using # for comment is preferred, but you can comment multi-line by heredoc:

1
2
3
: <<'END_COMMENT'
...
END_COMMENT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/usr/bin/env bash
#########################################################################
# Please insert the update at top of the logs
# Date Author Description
#
#########################################################################
## syntax check only, dry run
#set -n
## add line number for -x
export PS4='$LINENO + '
## pipeline subcommand failure check
set -o pipefail
## e: command line failure check
## u: undefined variable check
## x: print command executed
set -eux

## find canonical file path
## or you can restrict run script in it's current directory
CUR_PATH=$(dirname $(readlink -f $0))
source $CUR_PATH/<env file>
JQ="$CUR_PATH/jq"

## create log file for this script
OUT_FILE=$(mktemp /tmp/log.XXXX)
#OUT_FILE=/tmp/log

########################### function #########################
function exitHook {
rm -f $OUT_FILE
rm -f ${OUT_FILE}.out
rm -f ${OUT_FILE}.err
}
## clean job for log file, you can add other signals
trap exitHook EXIT

function usage() {
echo "<Description>"
echo
echo "Usage:"
echo " $0 [...]"
echo
echo "Flags:"
echo " -h, --help help info"
}

## this is for return json format messages
function returnError() {
msg="$1"
echo "{\"result\": \"Failure\", \"message\": \"$msg\"}" |${JQ} '.'
exit 1
}

function returnInfo() {
msg="$1"
echo "{\"result\": \"Success\", \"message\": \"$msg\"}" |${JQ} '.'
exit 0
}

########################## main ##############################
## declare input parameters
P1=""
P2=""

## check script parameters
if [[ $# -eq 0 ]]; then
msg="No command-line arguments were specified..."
returnError "$msg"
fi

while [[ $# -gt 0 ]]
do
case "$1" in
-p1|--p11)
shift
P1=$1
shift;;

-p2|--p22)
shift
P2=$1
shift;;

*) msg="$0: Bad Usage..."
returnError "$msg"
esac
done

## double check or restrict parameters
if [[ "X${P1}" = "X" ]]; then
msg="-p1 was not specified"
returnError "$msg"
elif [[ "X${P2}" = "X" ]]; then
msg="-p2 was not specified"
returnError "$msg"
fi

## then do the job, when you run some commands in script
## you can redirect the normal output to ${OUT_FILE}.out
## and error output to ${OUT_FILE}.err by:
command 1>>${OUT_FILE}.out 2>>${OUT_FILE}.err

if [[ $? = 0 ]]; then
msg="Run command successfully..."
returnInfo "$msg"
else
## parse err log file and return message
msg=$(cat ${OUT_FILE}.err|sed -e 's/"/\\"/g')
returnError "$msg"
fi
0%