Bash script template(Bash脚本模板)
废话不多说,献上我的模板
#!/usr/bin/env bash
set -Eeuo pipefail
trap cleanup SIGINT SIGTERM ERR EXIT
script_dir= ( c d " (cd " (cd"(dirname “${BASH_SOURCE[0]}”)" &>/dev/null && pwd -P)
usage() {
cat <<EOF
Usage: ( b a s e n a m e " (basename " (basename"{BASH_SOURCE[0]}") [-h] [-v] [-f] -p param_value arg1 [arg2…]
Script description here.
Available options:
-h, --help Print this help and exit
-v, --verbose Print script debug info
-f, --flag Some flag description
-p, --param Some param description
EOF
exit
}
cleanup() {
trap - SIGINT SIGTERM ERR EXIT
script cleanup here
}
setup_colors() {
if [[ -t 2 ]] && [[ -z “KaTeX parse error: Expected 'EOF', got '&' at position 17: …NO_COLOR-}" ]] &̲& [[ "{TERM-}” != “dumb” ]]; then
NOFORMAT=‘\033[0m’ RED=‘\033[0;31m’ GREEN=‘\033[0;32m’ ORANGE=‘\033[0;33m’ BLUE=‘\033[0;34m’ PURPLE=‘\033[0;35m’ CYAN=‘\033[0;36m’ YELLOW=‘\033[1;33m’
else
NOFORMAT=‘’ RED=‘’ GREEN=‘’ ORANGE=‘’ BLUE=‘’ PURPLE=‘’ CYAN=‘’ YELLOW=‘’
fi
}
msg() {
echo >&2 -e “${1-}”
}
die() {
local msg=$1
local code=${2-1} # default exit status 1
msg “$msg”
exit “$code”
}
parse_params() {
default values of variables set from params
flag=0
param=‘’
while :; do
case “${1-}” in
-h | --help) usage ;;
-v | --verbose) set -x ;;
–no-color) NO_COLOR=1 ;;
-f | --flag) flag=1 ;; # example flag
-p | --param) # example named parameter
param=“${2-}”
shift
;;
-?*) die “Unknown option: $1” ;;
*) break ;;
esac
shift
done
args=(“$@”)
check required params and arguments
[[ -z “${param-}” ]] && die “Missing required parameter: param”
[[ ${#args[@]} -eq 0 ]] && die “Missing script arguments”
return 0
}
parse_params “$@”
setup_colors
script logic here
msg “ R E D R e a d p a r a m e t e r s : {RED}Read parameters: REDReadparameters:{NOFORMAT}”
msg “- flag: ${flag}”
msg “- param: ${param}”
msg “- arguments: ${args[*]-}”
Choose Bash
#!/usr/bin/env bash
脚本为了获得最佳兼容性,它引用/usr/bin/env,而不是直接引用/bin/bash。
Fail fast
set -Eeuo pipefail
set命令可以更改脚本执行选项。例如,通常Bash不关心某个命令是否失败,返回非零退出状态代码。它只是快速地跳到下一个。现在考虑一下这个小脚本:
#!/usr/bin/env bash
cp important_file ./backups/
rm important_file
如果备份目录不存在,会发生什么情况?确切地说,你将在控制台中收到一条错误消息,但是在你能够做出反应之前,该文件已经被第二个命令删除。
Get the location
script_dir= ( c d " (cd " (cd"(dirname “${BASH_SOURCE[0]}”)" &>/dev/null && pwd -P)
这行代码尽其所能定义脚本的位置目录,然后我们对其进行cd配置。为什么?
通常,我们的脚本在相对于脚本位置的路径上运行,复制文件并执行命令,假设脚本目录也是一个工作目录。是的,只要我们从它的目录执行脚本。
但是,假设我们的CI配置执行脚本如下所示呢:
/opt/ci/project/script.sh
那么我们的脚本不是在项目目录中操作的,而是在CI工具的一些完全不同的工作目录中操作的。我们可以通过在执行脚本之前转到目录来修复它:
cd /opt/ci/project && ./script.sh
但从脚本的角度解决这个问题要好得多。因此,如果脚本从同一目录中读取某个文件或执行另一个程序,请按如下方式调用:
cat “$script_dir/my_file”
同时,脚本不会更改工作目录的位置。如果脚本是从其他目录执行的,并且用户提供了指向某个文件的相对路径,我们仍然可以读取它。
Try to clean up
trap cleanup SIGINT SIGTERM ERR EXIT
cleanup() {
trap - SIGINT SIGTERM ERR EXIT
script cleanup here
}
在脚本结束时,将执行cleanup()函数。你可以在这里尝试删除脚本创建的所有临时文件。
请记住,cleanup()不仅可以在最后调用,在任何时候都可以。
Display helpful help
usage() {
cat <<EOF
Usage: ( b a s e n a m e " (basename " (basename"{BASH_SOURCE[0]}") [-h] [-v] [-f] -p param_value arg1 [arg2…]
Script description here.
…
EOF
exit
}
尽量让usage()函数相对靠近脚本的顶部,有两种作用:
-
要为不知道所有选项并且不想查看整个脚本来发现这些选项的人显示帮助。
-
当有人修改脚本时,保存一个最小的文档(因为两周后,你甚至不记得当初是怎么写的)。
我不主张在这里记录每个函数。但是一个简短、漂亮的脚本使用这些消息是必需的。
Print nice messages
setup_colors() {
if [[ -t 2 ]] && [[ -z “KaTeX parse error: Expected 'EOF', got '&' at position 17: …NO_COLOR-}" ]] &̲& [[ "{TERM-}” != “dumb” ]]; then
NOFORMAT=‘\033[0m’ RED=‘\033[0;31m’ GREEN=‘\033[0;32m’ ORANGE=‘\033[0;33m’ BLUE=‘\033[0;34m’ PURPLE=‘\033[0;35m’ CYAN=‘\033[0;36m’ YELLOW=‘\033[1;33m’
else
NOFORMAT=‘’ RED=‘’ GREEN=‘’ ORANGE=‘’ BLUE=‘’ PURPLE=‘’ CYAN=‘’ YELLOW=‘’
fi
}
msg() {
echo >&2 -e “${1-}”
}
首先,如果你还不想在文本中使用颜色,那么先删除setup_colors()函数。我保留它是因为我知道如果我不必每次都用谷歌编码的话,我会更频繁地使用颜色。
其次,这些颜色只用于msg()函数,而不是echo命令。
msg()函数用于打印不是脚本输出的所有内容。这包括所有日志和消息,而不仅仅是错误。引用 12 Factor CLI Apps
的文章说法:
In short: stdout is for output, stderr is for messaging.
— Jeff Dickey, who knows a little about building CLI apps
stdout用于输出,stderr用于消息传递。
这就是为什么在大多数情况下你不应该为stdout使用颜色。
用msg()打印的消息被发送到stderr流并支持特殊的序列,比如颜色。如果stderr输出不是交互式终端,或者传递了一个标准参数,那么颜色将被禁用。 用法如下:
msg “This is a R E D v e r y i m p o r t a n t {RED}very important REDveryimportant{NOFORMAT} message, but not a script output value!”
要检查stderr是不是交互式终端时的行为,请在脚本中添加类似于上面的一行。然后执行它,将stderr重定向到stdout并通过管道将其发送到cat。管道操作使输出不再直接发送到终端,而是发送到下一个命令,因此颜色会被禁用。
$ ./test.sh 2>&1 | cat
This is a very important message, but not a script output value!
Parse any parameters
parse_params() {
写在最后
在结束之际,我想重申的是,学习并非如攀登险峻高峰,而是如滴水穿石般的持久累积。尤其当我们步入工作岗位之后,持之以恒的学习变得愈发不易,如同在茫茫大海中独自划舟,稍有松懈便可能被巨浪吞噬。然而,对于我们程序员而言,学习是生存之本,是我们在激烈市场竞争中立于不败之地的关键。一旦停止学习,我们便如同逆水行舟,不进则退,终将被时代的洪流所淘汰。因此,不断汲取新知识,不仅是对自己的提升,更是对自己的一份珍贵投资。让我们不断磨砺自己,与时代共同进步,书写属于我们的辉煌篇章。
需要完整版PDF学习资源私我
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!