1) 使用 /bin/bash 还是 /usr/bin/env bash
bash脚本的开头,通常声明为#!/bin/bash
,但一些严谨一些(为了更好的跨平台)的脚本里,声明为#!/usr/bin/env bash
并不是所有的操作系统上bash
都是/bin
路径下的,有些unix(比如bsd系列),bash不是它们的默认shell,安装路径可能是在/usr/local/bin/bash
,所以通过env
方式在path
下选择bash
兼容性更好一些。不过,如果确定脚本只是为linux和mac使用,也无所谓。
2) 标准输入使用”-” ,还是”/dev/fd/0″
相对于使用”-“表示标准输入,”/dev/fd/0″的一个好处是,在脚本里更明确一些,因为有时很难区分”-“到底代表标准输入,还是命令的参数。
/dev/fd/0 标准输入
/dev/fd/1 标准输出
/dev/fd/2 标准错误
3) 获取当前目录
有好几种方式可以获取当前运行的脚本所在的目录,最严谨的一种方式是:
CUR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd -P )"
4) set -e 要不要设置
有些情况下,我们需要判断上一条命令是否执行成功,比如kill -0 pid
检查某个进程是否存在,这个时候如果设置了set -e
,导致进程不存在的kill -0
执行失败脚本退出。如果进程不存在的也有一个分支逻辑的话,那个分支就不可能执行到了,这种情况下显然不能使用set -e
5) exit与fork
exit
通常是当某个执行失败或条件不符合时希望真个脚本退出时使用的,但需要注意的一点是,当使用”$()”执行一个函数时,是fork方式,这个函数里定义的exit
是让fork
的那个进程退出,而不是当前脚本进程,需要当前脚本退出的话,一个变通的方式是定义个类似exit的方法给最顶层的进程发信号:
TOP_PID=$$
trap "exit 1" TERM
quit() {
local msg=$1
[ ! -z "$msg" ] && echo $msg >&2
kill -s TERM $TOP_PID
}
foo() {
command || quit
}
result=$(foo)