bash的几个细节

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)

发表评论

电子邮件地址不会被公开。 必填项已用*标注