if
ステートメントに到達するまで、すべてのコマンドを実行するスクリプトがあります。
スクリプト:
#!/bin/bash
######VARIABLES#######
#grep return value
gret=$?
######LOGIC#######
cd /home/logs
echo "Enter filename: "
read filenamex
echo "filename : ${filenamex}"
grep ${filenamex} log.dat | grep "End receiving ftp file:"
echo $?
if [ {gret} -ne 0 ]; then
echo "{filenamex} cannot be found in the recent logs. We will now check the old logs."
sleep 3
grep ${filenamex} log.dat* | grep "End receiving ftp file:"
fi
grep
必要な値を取得できない場合、スクリプトがif
文を実行できるようにスクリプトを実行するのに役立つ人はいますか?
答え1
$
コードの主な問題は、テストに欠けているもの(またはまだ良いものでなければならない{gret}
)${gret}
と終了ステータスを変数に"$gret"
割り当てないことです(以下のようにwithを直接使用する場合は実際には必要ありません)。 。grep
gret
grep
if
if
ステートメントの終了状況は、ステートメントで直接使用できます。次のコードでは、対話形式で要求するのではなく、コマンドライン引数としてファイル名を要求します。
#!/bin/sh
if [ -z "$1" ]; then
echo 'Expected to get a filename as argument'
exit 1
fi >&2
if ! grep -Fe "$1" /home/logs/log.dat | grep -F 'End receiving ftp file:'
then
echo 'Checking older logs...' >&2
grep -Fe "$1" /home/logs/log.dat?* | grep -F 'End receiving ftp file:'
fi
上記のコードは、パターンが正規表現として解釈されるのを防ぎ、パターンがダッシュで始まる場合、オプションセットとして間違えるのを防ぐために-F
withを使用します。与えられた文字列を正規表現として使用するには、各パイプの最初の文字列からその文字列を削除します。grep
-e
-F
grep
grep
ファイル名ワイルドカードパターンは、実際の名前自体ではなくで始まる名前と/home/logs/log.dat?*
一致します。名前の最初の接頭辞の後に少なくとも1つの追加文字を要求することによってこれを行います。/home/logs
log.dat
log.dat
log.dat
特定の機能を使用していないため、スクリプトをsh
スクリプトに置き換えました。bash
ほぼ同じgrep
パイプラインを2回繰り返さないように、上記のコードをリファクタリングします。
#!/bin/sh
if [ -z "$1" ]; then
echo 'Expected to get a filename as argument'
exit 1
fi >&2
do_grep () {
pattern=$1; shift
grep -Fe "$pattern" -- "$@" |
grep -F 'End receiving ftp file:'
}
if ! do_grep "$1" /home/logs/log.dat; then
echo 'Checking older logs...' >&2
do_grep "$1" /home/logs/log.dat?*
fi