bashネタめげた

量が。。

しかしまぁ、bashは便利(比較対象:sh)。
testとか[ の替わりに、複合コマンドの[[ ] ]をつかうと、

hoge=

if [[ -z $hoge ]];then
    echo hoge is empty
fi

と書ける。これがtestだと

hoge=

if [ -z "$hoge" ];then
    echo hoge is empty
fi

みたいに、ダブルクオート必須。

算術演算もサポートしているので

hoge=3

if (( 2 < $hoge && $hoge < 4 ));then
  echo OK
fi

とか、結構直感的な感じで書ける。これがtestだと

hoge=3

if [ 2 -lt $hoge -a $hoge -lt 4 ];then
  echo OK
fi

とか、ltって何だっけとか-aってなんだっけとか、面倒くさい。
論理演算をグルーピングするときも

hoge=3

if (( (2 < $hoge) && ($hoge < 4) ));then
  echo OK
fi

とふつーに書ける。testコマンドだと、(がbashにメタ文字と認識されないように

hoge=3

if [ \( 2 -lt $hoge \) -a \( $hoge -lt 4 \) ];then
  echo OK
fi

と書く必要あり。メンドクセー。


一番便利なのが、コマンドの置換。バッククオート(`)って見えないよ。
bashだと$()がバッククオート代わりに使えるし、ネストも出来る。

greeting=Hello
you=world

echo $(echo ${greeting} $(echo ${you})\!)

このネストしてコマンドが実行できることを利用すると。
http://emasaka.blog65.fc2.com/blog-entry-446.html
みたいに、lispぽい書き方ができる。
このやり方は、マクロプロセッサ業界の中ではポピュラーなのか、GNU Makeの本にも同じような例が出てた。


注意が必要なのが、while でreadするとき。

hoge=fuga

echo hoge | while read i; 
    do hoge=$i; 
    echo "hoge=$hoge"; 
done

と実行すると。「echo "hoge=$hoge"; 」で「hoge」が表示されるんだけど、
while ループを抜けたあとに「echo "hoge=$hoge"; 」すると、「fuga」が表示される。
これは、パイプ処理でwhileの中がサブシェルで実行されているため。
サブシェルが起動される条件は、↓が詳しい。
http://dsas.blog.klab.org/archives/50703133.html


解決策としては、readに渡すのに、パイプを使うのではなく、リダイレクトで渡すとOK。

hoge=fuga

while read i; 
    do hoge=$i; 
    echo "hoge=$hoge"; 
done <<END
hoge
END

ファイルから読む場合でも

echo hoge > file.txt

while read i; 
    do hoge=$i; 
    echo "hoge=$hoge"; 
done < file.txt

とファイルを標準入力につなげれば大丈夫。

どーでもいいはなし

bashでwebページからデータをGETしてくることも出来る。

exec 5<> /dev/tcp/yahoo.co.jp/80
echo -e "GET / HTTP/1.0\n" >&5
cat <&5

出典:http://tldp.org/LDP/abs/html/devref1.html