私は次の行を含むこのスクリプトを書いています。
ls -lrt /dir1/dir2/filename*.txt | tail -1 | awk '{print $9}' | read variable
私が望むのは、一致するものがない場合はif文を使用せずにスクリプトを終了することです。
ベストアンサー1
このコマンドを書く方法
この特定の操作にはパイプラインは必要ありません。
zshから:
a=(/dir1/dir2/filename*.txt(Nom[1]))
if ((! #a)); then
echo >&2 "No file matches /dir1/dir2/filename*.txt"
exit 2
fi
variable=$a[1]
あるいは、globが一致しない場合は、自動的にスクリプトを終了します。
set -e
a=(/dir1/dir2/filename*.txt(om[1]))
variable=$a[1]
他のシェルには最新のファイルを見つける機能が組み込まれていません。ファイル名に改行文字以外の印刷可能文字のみが含まれている場合、呼び出しはls
合理的ですが、オプションを渡さなかった名前を-l
除くすべての文字を解析します。これは不必要に複雑で壊れやすい(特に空白割り込み)。また、sortの最後の項目-t
を取得するよりも高速なsortの最初の項目を取得します-tr
。直接方法:
variable=$(ls -td /dir1/dir2/filename*.txt 2>/dev/null | head -n 1)
if [ -z "$variable" ]; then
echo >&2 "No file matches /dir1/dir2/filename*.txt"
exit 2
fi
処理パイプライン
パイプの左側が失敗した場合(つまり、ゼロ以外の状態で終了するか、シグナルによって終了した場合)、スクリプトを中断するには、ksh93とbashでオプションを設定し、pipefail
パイプ状態をゼロ以外にすることができます。
set -e -o pipefail
somecommand | filter
echo "somecommand succeeded"
または
set -o pipefail
if ! somecommand | filter; then
echo >&2 "somecommand or filter failed"
exit 2
fi
Zshのオプションはありませんが、pipefail
配列内のパイプラインの各コンポーネントのステータスコードを取得できますpipestatus
。
somecommand | filter
if ((pipestatus[1])); then
echo >&2 "somecommand failed"
exit 2
fi
他のシェルでは、パイプの状態は右側のコマンドの状態です。左のコマンドの状態を検索する直接的な方法はありません。バラより終了状態を別のプロセスにパイプにインポートするいくつかの可能な解決策。
filter
の完全な出力を読む必要があります。それ以外の場合は、死んだときに何が起こるのかをsomecommand
処理する必要があります。somecommand
信号パイプライン。
somecommand
終了状態ではなく出力を生成するかどうかに応じてアクションを実行するには、次のようにします。ifne
~からJoey Hessのmoreutils。ほとんどのシステムでは、デフォルトでこれらのユーティリティはインストールされていません。