2005-09-29
_ シェルスクリプト
kshで作成されたスクリプトをLinuxでも動くようにと投げられた仕事をもくもくとやっていたわけですが,どうにもうまく動かずに困ったこと.kshとbashで微妙に違うんだろうなぁ.以下のようなテキストファイルを読み込んで記述されているディレクトリ名なんかを変数に代入しています.
# # sample.lst # 管理者: hoge # 更新者: fuga # 2005/09/29 !/hoge/build foobar.xml build SOURCE !/hoge/classes/com/smallstyle/common hogehoge.class java_batch SMP000 !/hoge/java/com/smallstyle/common hogehoge.java java_batch SMP000
上記のテキストファイルを読み込んで変数に代入してるkshの部分のコードが,下.
# (空行・コメント行は読み飛ばし) egrep -v "^$|^#" /hoge/sample.lst | while read sTmpLine do # 先頭が!であればディレクトリ名取得 if [[ "${sTmpLine}" != "${sTmpLine#'!/'}" ]] then # レコードからディレクトリ名を取得 local sTmpDirName="${sTmpLine#'!'}" sTmpDirName="${sTmpDirName%'/'}" else # レコードからファイル名を取得 local sTmpFileName=$(echo "${sTmpLine}" | awk -F '\t' '{ print $1 }') # フルパスファイル名を変数へ設定 sTgtDevFileName="${sTgtDevFileName} ${sTmpDirName}/${sTmpFileName}" fi done
上記のコードそのものはちゃんとテキストファイルから読み取って変数sTgtDevFileNameに代入してくれるのですが,Linux上で実行するとwhile文の外でこのsTgtDevFileNameをechoしてみても中身が空っぽなのです.whileのループで中で変数の中身をechoしてみるとちゃんと代入されている感じ.でもループを抜けると消えてしまいました….もとのコードを書いた人に確認できればいいのですが,そうもできないみたいなので,適当に書き換えることに.とりあえずは以下のようにしてみた.
while read sTmpLine do # 空行・コメント行は読み飛ばし if [[ "{sTmpLine}" != "{sTmpLine#'#'}" ]] then continue elif [[ -z "${sTmpLine}" ]] then continue # 先頭が!であればディレクトリ名取得 elif [[ "${sTmpLine}" != "${sTmpLine#'!/'}" ]] then # レコードからディレクトリ名を取得 local sTmpDirName="${sTmpLine#'!'}" sTmpDirName="${sTmpDirName%'/'}" else # レコードからファイル名を取得 local sTmpFileName=$(echo "${sTmpLine}" | awk -F '\t' '{ print $1 }') # フルパスファイル名を変数へ設定 sTgtDevFileName="${sTgtDevFileName} ${sTmpDirName}/${sTmpFileName}" fi done < /hoge/sample.lst
もう少しスマートな書き方がありそうな気がしてならないけど,とりあえず時間を優先ということでこれで手を打つ.上のコードでも別に問題なさそうなのになんでだめなのかがやっぱり納得いかないなぁ….