より読みやすく、同様のコマンドのリストをより明確にしたいので、少しのターミナルループを作成しました。
for what in \
cache \
thumbs \
; do my template $what:clear; done
うまくいきますが、
my template cache:clear && my template thumbs:clear
簡単で明確に配置する方法はありませんか?&&このようなループで作業すると最後のコマンド終了コードを確認するために、ループ本体にif / elseステートメントを追加し、ゼロ以外の場合にブレークを呼び出すのは複雑ではありませんか?
条件が十分であれば:
for what in \
cache \
thumbs \
; do
my template $what:clear;
if [ $? -ne 0 ]; then break; fi \
; done
答え1
あなたが使用できるset -e
:
(set -e;
for what in \
cache \
thumbs;
do my template $what:clear; done)
set -e
コマンドがゼロ以外の終了コードで終了したときにシェルを終了させ、失敗は他に処理されません。上記でmy ...
失敗すると、サブシェル全体が終了し、サブシェルの終了コードは失敗したコマンドの終了コードです。これはシェルスクリプトとコマンドラインで機能します。
別の方法は分離を使用することです。
for what in \
cache \
thumbs; do
my template $what:clear || break
done
欠点は、|| break
すべてのコマンドの後に必要であり、失敗を示す終了コードを無視することです。ループはfor
毎回ゼロの終了コードで終了します。終了コード1を使用してループを終了させるフェイルオーバーを設定することで、break
これを回避できます(これは上記のサブシェルアプローチよりも劣っています)。for
for what in \
cache \
thumbs; do
my template $what:clear || break -1 2>/dev/null
done
(ゼロ以外の終了コードで終了し、対応するbreak -1
エラーメッセージを削除します。)break
2>/dev/null
私が知っている限り、&&
終了ループのような&& done
ものは使用できません。
答え2
エラーが発生した場合、ループを終了する直接的な方法はありません。最も明確な方法はwhile
ループの代わりにループを使用することですが、for
これはリストの反復と簡単には組み合わせられません。リストを変数に組み合わせてからリストから要素を明示的に削除する必要があるため、コードがより複雑になります。
items=(cache thumbs);
while ((${#items[@]})) && my template "${items[0]}":clear; do shift items; done
((${#items[@]} == 0)) # to check if all the items were processed
ステートメントを使用するよりも書くより短い方法if
は次のとおりです。
for what in cache thumbs; do
my template "$what":clear || break;
done
ブール演算子の使用は通常、ブール演算子を使用するよりも読みやすくなりますが、if
かなりsomecommand || fallback
慣用的です。
for
ループは常に成功します。コードが早く終了するかどうかを知る便利な方法はありません($what
最後の項目がループの後ろにあるかどうかをテストできますが、これには最後の項目が何であるかを知るための便利な方法が必要です。最後の項目が正常に処理されました)
これは複数のコマンドに合わせて拡張されません。代わりにオンにすることもできますエラーが発生したため終了Mode with set -e
。コマンドが失敗すると、シェルはすぐに終了します(簡単な場合 - 詳細は非常に複雑ですが、ここでは十分です)。包含ループ、包含関数、または包含スクリプトだけでなく、フル(サブ)シェルも終了します。スクリプトの一部のみを終了するにはサブシェル。変数の変更はサブシェル全体で維持されません。
( set -e;
for what in cache thumbs; do
my template "$what":clear;
done
)
# Here $? is 0 if all the mv commands succeeded and nonzero otherwise