シェルやってる人は何か書いてください。
目次
スクリプト内にEOFを記載する場合、EOFの前にスペース等を入れてはならない。
unexpected end of file エラーになります!(経験談)
コマンドラインから入力した値が、数値なのか文字列なのか判定したいんですけど・・・という時。
read C_LINE expr $C_LINE + 0 > /dev/null 2>&1 _STATUS=$? if [ $_STATUS != 0 ] ; then echo "入力した値は文字列です。" else echo "入力した値は数値です。" fi
解説は気が向いたら書きます。
結構分からなくなるリダイレクトについてのまとめ。
コマンド結果をファイルに出力したいとき。
command > file_name 例) ls -l > file_name.txt
この場合、標準出力はfile_name.txtに吐かれるが、実行したコマンドが
エラーだった場合、エラーメッセージはファイルに出力されない。
コマンド結果および、エラーメッセージをファイルに出力したいとき。
command > file_name 2>&1 例) find / -name hoge > file_name.txt 2>&1
確かこうするとファイルディスクリプタ2(標準エラー)もリダイレクトで
FD1(標準出力)に向いているため、file_name.txtへエラーメッセージも出力される。
逆に、エラーのみファイルに出力したいという場合は以下のとおり。
command 2>file_name 例) cat hoge.txt 2>file_name.txt
コマンドの結果をコマンドに渡したいときはパイプ(|)でいける。
標準エラーもコマンドに渡したいという場合はパイプとリダイレクトを組み合わせる。
command 2>&1 | command 例) find . -name keyword 2>&1 | wc
標準エラーだけコマンドに渡したいとき。
(command 3>&1 >/dev/null 2>&3 3>&-) | command 例)(find . -name keyword 3>&1 >/dev/null 2>&3 3>&-) | wc
実はFD3なんか使わなくても下でいける。
command 2>&1 >/dev/null | wc 例) find . -name keyword 2>&1 | wc
とは言え、FD1とFD2以外のFDを使うのは意外とお役立ち。
例えば設定ファイルを1行ずつ読み込んで処理するようなシェルスクリプトがよくある。
while文でファイルを読み込めば良いかなぁとかそんな感じ。
例:設定ファイルに記載されてるファイルをlsするスクリプト(hoge.sh)
#!/usr/bin/sh
zCur=`pwd`
zLog="${zCur}/logfile.log"
zConfFile="${zCur}/hoge.conf"
# exit function (normal)
function f_exit
{
echo "`date` - Script Normal End. Code:[${nRet}]" >> ${zLog}
exit $nRet
}
# exit function (abnormal)
function f_abexit
{
echo "`date` - Script Abnormal End. Code:[${nRet}]" >> ${zLog}
exit $nRet
}
# main
echo "`date` - Script Start." >> ${zLog}
exec 3<&0 <${zConfFile}
while read zHoge
do
echo "`date` - reading config file... value:[${zHoge}]" >> ${zLog}
zLsRet=`ls -l ${zHoge} 2>&1`
nRet=$?
if [ ${nRet} -ne 0 ]; then
echo "`date` - ${zHoge} file does not found." >> ${zLog}
echo "`date` - ls command return:[${zLsRet}]" >> ${zLog}
f_abexit
else
echo "`date` - ls command return:[${zLsRet}]" >> ${zLog}
fi
done
exec 0<&3 3<&-
f_exit
#EOF
例:設定ファイル(hoge.conf)
hoge.sh hoge.conf fuga.log
例:カレントディレクトリのls結果
hoge.conf hoge.sh
設定ファイルを読むところで、
exec 3<&0 <${zConfFile}
while read zHoge
うんぬん
exec 0<&3 3<&-
ではなく、下のようにしても出来ないこともない。
cat ${zConfFile} | while read zHoge
ただ、こうすると問題が発生する場合がある。
while内の処理はhoge.shの子プロセスが行っているので、
while内の変数に入った値は親(hoge.sh)に反映されない。
つづく・・・