for
対話型セッションでループを開始しますbash
。この問題では、ループが次のようになると想定できます。
for i in dir/*; do
program "$i"
done > log
コマンドは予想よりはるかに長くかかりましたが、まだ実行されました。for
現在実行中のループの進行状況を表示する方法。
非ソリューション:
- より
log
。
次の理由で機能しません。program
静かに走ると予想されます。program
検証人だと思えばいいです。出力なしでループが完了したら幸いです。 - サイクルを停止します。一種の進行状況インジケータを追加します(例
echo "$i"
:)。サイクルを再開してください。
次の理由で機能しません。ループは数時間実行された。私は現在それに投資しているすべての時間とエネルギーを無駄にしたくありません。私はすべてが大丈夫だと思います。ただ気になって、今まで何が起こっているのか知りたいです。 - Ctrl+Zそれから
set -x; fg
次の理由で機能しません。bash
使用中はサイクルは継続されませんfg
。ループ内の現在/次のコマンドが実行されるまで、ループは終了しませんfg
。自分で試してみてくださいfor i in {1..200}; do printf '%s ' $i; /usr/bin/sleep 0.5; done
。
ベストアンサー1
ワイルドカード文字はdir/*
常に同じ順序で展開されます。この機能は現在の値と一緒に使用して$i
進捗情報を表示できます。
$i
現在の値は、システムで実行されているプロセスを確認することによって取得できます。これ次のコマンド現在実行中のインスタンスprogram
とそのパラメータを印刷します。
複数のプロセスがある場合は、確認したいループを実行しているシェルで開始されたプロセスのみを一致させるオプションをprogram
使用できます。--parent ...
pgrep
for
ps -o args= -fp $(pgrep program)
手動で値を抽出し、$i
次を使用して進行状況を確認します。
a=(dir/*)
n=$(printf %s\\0 "${a[@]}" | grep -zFxnm1 'the exact value of $i' | cut -f1 -d:)
echo "Progress: $n / ${#a[@]}"
これは2つの仮定の下で機能します。
dir/
ループの実行中は内容は変更されません。program
ファイルが作成された場合、名前が変更または削除された場合は、番号が間違っている可能性があります。program
新しいプロセスを開始するために呼び出されます。関数program
の場合、bash
子プロセスはありませんprogram
。関数function
自体が新しいプロセスを開始する別のプログラムを呼び出す場合は、そのサブルーチンを見つけることができます。しかし、program
bash 組み込み(ネストされたコマンドを使用help
)または純粋な bash 関数(組み込みbash
機能を使用)の場合、幸運ではありません。
問題2があるfor
場合、またはループの構造が質問と異なる場合(たとえば、さまざまなプログラムを含む非常に長いループ本文)、プロセスを調べることで問題を解決program < "$1"
できます。lsof