- 海之寻趣
- Ranler
- 2016-05-20 14:18
- CC BY-NC-SA
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