Shell Idioms
目录

1. 获得当前程序文件的绝对路径

TOP_DIR=\$(cd \$(dirname "$0") && pwd)

2. 条件正则匹配(Bash)

if [[ \${OS} =~ (rhel[3-6])]];then
echo "yes"
else
echo "no"
fi

比如要匹配多个选项:

if [[ \${DISTRO} =~ (oneiric|precise|quantal|raring|saucy|7.0|wheezy|sid)]];then
echo "yes"
else
echo "no"
fi

3. 脚本同时只有一个实例

lockfile=/var/tmp/mylock

if ( set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null; then

trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT

# do stuff here

# clean up after yourself, and release your trap
rm -f "$lockfile"
trap - INT TERM EXIT
else
echo "Lock Exists: $lockfile owned by $(cat $lockfile)"
fi

4. 脚本参数设置和子命令输出解析

FREE=$(df /media/mp3 | awk '/^\/dev/ {print $4}')

set -- $(df /media/mp3 | grep '^/dev/')
FREE=$4

set --可以重新设置当前脚本或函数的参数,重新绑定$1,$2...。 因此可以用set --解析子命令的输出,把输出结果按空格分割绑定到$1...上。 示例中的set --也等价于第一行的命令。

5. 执行一个后台进程并脚本结束时kill掉

BACKGROUND_CMD=...
(
${BACKGROUND_CMD}
) > file.log  &
B_PID=$!

FOREGROUND_CMD_EXEC...

kill ${B_PID}
wait ${B_PID}
ehco $?

另一个问题:How can I kill and wait for background processes to finish in a shell script when I Ctrl+C it?

#!/bin/bash
trap 'killall' INT

killall() {
trap '' INT TERM     # ignore INT and TERM while shutting down
echo "**** Shutting down... ****"     # added double quotes
kill -TERM 0         # fixed order, send TERM not INT
wait
echo DONE
}

./process1 &
./process2 &
./process3 &

cat # wait forever

6. trace内容输出到文件

set +x
## write log to fd4
TRACEFILE=${LOG_PATH}/trace.log
exec 4>$TRACEFILE
#exec 2>$TRACEFILE
#exec 1>$TRACEFILE
BASH_XTRACEFD=4
set -x


...


set +x
unset BASH_XTRACEFD
exec 4>&-
#exec 2>&-
#exec 1>$-
set -x

7. 替换换行符

$sed ':a;N;$!ba;s/\n/ /g' file.txt   # 替换换行符为空格
$tr "\n" " " < file.txt

8. 打印毫秒

$ date +%s.%3Ns      # 开机后的秒数,毫秒保留3位数字
1440573628.457s

9. find忽略一些路径

find . -path ./misc -prune -o -name '*.txt' -print
find . -type d \( -path dir1 -o -path dir2 -o -path dir3 \) -prune -o -print

参考

发表评论