wd and cc

-- Good good study, day day up!

Some tips for bash scripting

#Web

最近几天写了一些 bash 脚本,又有些心得,记录一下。

获取当前路径的绝对路径

比较常见的需求可能是获取相对路径,这样方便程序复制到其他目录也可以运行。使用 $(dirname $0) 就可以获取相对路径,不过这里说的是绝对路径。

其实也简单,相对路径加上当前目录,那不就是绝对路径么。不过是,有时候 $(dirname $0) 取到的也可能是绝对路径(一般期望相对路径的程序也能跑通,所以不大关心)。

可以用下面的做法,大意是先判断一下获取到的路径是不是 / 开头,如果是,那就不处理,如果不是,那就把当前的路径附加上去得到一个绝对路径。

1PG_DIR="$(dirname $0)/../"
2
3echo "$PG_DIR" | grep -q ^/
4
5if [ $? -ne 0 ];then
6        PG_DIR="$(pwd)/$PG_DIR"
7fi

使用 getopt 获取命令行参数

获取参数比较常见的做法是取 $1 $2 这些,不过不太专业,这里说的是类似于 --prefix=/path/to/install -v 这种。

bash 本身提供了一个内部命令 getopts 来做这个事情,不过那个只能支持 short_opts,就是类似 -v 这种,不支持长的。

getopt 是一个 GNU 程序,他支持 long_opts。下面是个例子。代码基本来自网上。

 1ARGS=$(getopt -a -o h -l initdb::,help -- "$@")
 2[ $? -ne 0 ] && usage
 3
 4eval set -- "${ARGS}" 
 5
 6while true
 7do
 8        case $1 in
 9                --initdb)
10                        initdb $2
11                        ;;
12                -h|--help)
13                        usage;
14                        ;;
15                --)
16                        shift
17                        break
18                        ;;
19        esac
20        shift
21done

解释一下上面的参数的含义:

find exec 提示 No such file or directory

这个是之前用来日志删除的一个程序,大概命令类似 find ./ -name '2012*' -exec rm -r {} \;,后来总发现报 No such file or directory 这个错误,可是去看的时候,发现那些目录也被删掉了。开始觉得可能是有其他人的程序也在删除这个目录,问了一圈结果没人删。

后来经过测试琢磨找到原因了,在于这个命令的执行思路大概是先去找那个名字的文件或者目录,然后挨个执行后面的命令。那么,如果找到的既有上级目录,也有下级文件的时候,如果目录先被删掉了,那删文件的时候可不就是 No such file or directory 么。

好在 find 提供了一个参数 -prune

       -prune True; if the file is a directory, do not descend into it. If -depth is given, false; no effect.  Because -delete implies -depth, you can-
              not usefully use -prune and -delete together.
comments powered by Disqus