シェルスクリプト総合 その4

このエントリーをはてなブックマークに追加
556名無しさん@お腹いっぱい。
サブシェルの問題だと思うが、そのコードだと説明不十分
たとえば下のコードならちゃんと 10 と出る。(Sol8)

#!/bin/sh
count=0
while [ $count -lt 10 ]
do
 count=`expr $count + 1`
 echo "count=$count"
done
echo "last:$count"

サブシェルの問題はUNIX FAQに載ってる
http://www.nurs.or.jp/~asada/FAQ/UNIX/section3.8.html
557554:2005/12/10(土) 23:17:02
>>555-556
ありがとうございますた。

とりあえず下記のサンプルで試してみました

パターン1
----------------
#!/bin/sh
COUNT=0
while read i
do
    COUNT=`expr $COUNT + 1`
    echo "now count = $COUNT"
done < /etc/passwd
echo "Last count = $COUNT"
----------------

パターン2
----------------
#!/bin/sh
COUNT=0
cat /etc/passwd | while read i
do
    COUNT=`expr $COUNT + 1`
    echo "now count = $COUNT"
done
echo "Last count = $COUNT"
----------------
558554:2005/12/10(土) 23:17:33
パターン3
----------------
#!/bin/sh
COUNT=0
exec 9<&0 < /etc/passwd
while read i
do
    COUNT=`expr $COUNT + 1`
    echo "now count = $COUNT"
done
exec 0<&9 9<&-
echo "Last count = $COUNT"
----------------

そうしたら、パターン1とパターン2のLast countは0のままで、
パターン3は正確な値がでました。
ちなみにパターン1のシェル指定を/bin/bashに変えたらあっさりと
正確な値が出たので、とりあえずはbashで逃げることにします。(;´Д`)
559名無しさん@お腹いっぱい。:2005/12/10(土) 23:33:09
>>558
bashismですね。
560名無しさん@お腹いっぱい。:2005/12/11(日) 01:13:02
bourne シェルの有名な欠点だな。

kshにすれば、パターン1もパターン2も値を引き継げる。

ちなみに、bashは変態仕様なんで、
パターン1は値を引き継げるけど、パターン2はダメ。
561 :2005/12/11(日) 01:56:05
うん、Solaris決め打ちでいいならkshにすべきだよね。
562名無しさん@お腹いっぱい。:2005/12/11(日) 03:10:01
zsh も、ksh と同様パターン1〜パターン3全て動くんだよね。

ksh だと対話的に使った場合の機能がちょっと足らんという場合、
bash を使う人が多いんだけど、zsh の方が幸せだと思う。

スクリプトで使う場合には、ksh の方が小さいからいいだろうね。
563名無しさん@お腹いっぱい。:2005/12/11(日) 03:40:29
>>560
bash はパイプライン中に変数を定義しても
ダメみたいだな。

$ bash
$ a=1
$ echo $a
1
$ ls | a=2
$ echo $a
1