端末コマンドテンプレートループで&&演算子を使用できますか?

端末コマンドテンプレートループで&&演算子を使用できますか?

より読みやすく、同様のコマンドのリストをより明確にしたいので、少しのターミナルループを作成しました。

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エラーメッセージを削除します。)break2>/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

関連情報