TAG

首都機能移轉 (2) 歌詞 (2) 靠北文 (40) 戲言 (30) 糟糕 (7) ACG (23) Assembly (2) Boost (2) C (31) C++ (69) CMake (4) CSIE (67) Debian (34) Design_Pattern (2) Django (1) Eclipse (1) en_US (13) FFmpeg (3) FoolproofProject (26) FreeBSD (2) Git (4) GNU_Linux (65) IDE (5) Java (11) JavaScript (19) KDE (15) Khopper (16) KomiX (3) Kubuntu (18) Life (1) Lighttpd (2) Mac_OS_X (2) Opera (1) PHP (2) PicKing (2) Programing (21) Prolog (1) Python (7) QSnapshot (2) Qt (30) Qt_Jambi (1) Regular_Expression (1) Shell_Script (7) Talk (98) VirtualBox (7) Visual_Studio (13) Windows (18) zh_TW (36)

2009年9月1日 星期二

Pitfalls in shell scripts

When you iterate paths and do something with them, you might be tempted write this:
find . -name blah | xargs rm -f
yeah, I know there is a switch -exec in find, I just don't like it.
This command looks fine, but has two problems:
  1. The length of arguments maybe exceeds the limit of the shell.
  2. The file path may contains some special characters, such like quotes, spaces.
To solve the first issue, a loop maybe useful:
for path in `find . -name blah` ; do
    rm -f "path"
done
This solves the first issue, but the second one remains. For loop treats spaces and newlines as delimiters. But if paths contain spaces, they will cause error.
You can change the delimiter temporary as a workaround, but this will impacts all actions in the loop, I personally don't recommend this.
Or we can use a while loop:
find . -name blah | while read path ; do
    rm -f "$path"
done
should be just fine.
Another common error , comes from:
if [ $str = blah ] ; then
The problem is, $str maybe unset or a null string, or worse, injected with a string such like -f.
Good practice is:
if [ x"$str" = xblah ] ; then

沒有留言:

張貼留言