シェル


シェル

シェルやってる人は何か書いてください。

目次

その他

EOFの場所について

スクリプト内に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)に反映されない。
つづく・・・