時間がかかるスクリプトを開始する場合、スクリプトを開始した後で必然的にそれを認識し、スクリプトが終了したら何らかの警告を表示する方法があったらいいのにと思います。
したがって、たとえば、私が実行した場合:
really_long_script.sh
enterキーを押します...完了後に別のコマンドを実行するにはどうすればよいですか?
複数のコマンドを;
で区切ることができるため、コマンドは順次実行されます。次に例を示します。
really_long_script.sh ; echo Finished
スクリプトがreturn-code 0(通常は正しく実行されたことを意味する)で終了した場合にのみ次のプログラムを実行する場合は、次のようにします。
really_long_script.sh && echo OK
反対の場合(つまり、現在のコマンドが失敗した場合にのみ続行する)は、次のようになります。
really_long_script.sh || echo FAILED
スクリプトをバックグラウンドで実行できます(ただし、スクリプトの出力(stdout
およびstderr
)は、どこかにリダイレクトしない限り、引き続きターミナルに送信されます)。次にwait
それのための:
really_long_script.sh &
dosomethingelse
wait; echo Finished
すでにスクリプトを実行している場合は、Ctrl-Z
を使用してスクリプトを一時停止し、次のように実行できます。
fg ; echo Finished
ここで、fg
は、中断されたプロセスをフォアグラウンドに移動します(bg
は、&
で開始した場合とほぼ同じように、バックグラウンドで実行します)
Bashのジョブコントロールを使用することもできます。始めたら
$ really_long_script.sh
次に、Ctrl + Zを押して一時停止します。
^Z
[1]+ Stopped really_long_script.sh
$ bg
(really_long_script.sh &
で開始した場合と同様に)ジョブをバックグラウンドで再開します。次に、このバックグラウンドジョブを待つことができます
$ wait N && echo "Successfully completed"
ここで、NはジョブID(他のバックグラウンドジョブを実行していない場合はおそらく1)で、上記の[1]
としても表示されます。
プロセスが現在のttyで実行されない場合は、次のことを試してください。
watch -g ps -opid -p <pid>; mycommand
これはそれほど難しいことではありません。既存のコマンドの実行中に次のコマンドをウィンドウに入力し、Enterキーを押すだけです。最初のコマンドが完了すると、2番目のコマンドが自動的に実行されます。
もっとエレガントな方法があると思いますが、これはうまくいくようです。
コマンドが完了した後にアラートを実行したい場合は、追加して編集します。これらのエイリアスを.bashrcに作成し、実行中にalert
を実行できます。
alias alert_helper='history|tail -n1|sed -e "s/^\s*[0-9]\+\s*//" -e "s/;\s*alert$//"'
alias alert='notify-send -i gnome-terminal "Finished Terminal Job" "[$?] $(alert_helper)"'
少し前に、別のプロセスの終了を待つスクリプトを作成しました。 DISPLAY
が正しく設定されている場合、NOISE_CMD
はnotify-send ...
のようになります。
#!/bin/bash
NOISE_CMD="/usr/bin/mplayer -really-quiet $HOME/sfx/alarm-clock.mp3"
function usage() {
echo "Usage: $(basename "$0") [ PROCESS_NAME [ PGREP_ARGS... ] ]"
echo "Helpful arguments to pgrep are: -f -n -o -x"
}
if [ "$#" -gt 0 ] ; then
PATTERN="$1"
shift
PIDS="$(pgrep "$PATTERN" "$@")"
if [ -z "$PIDS" ] ; then
echo "No process matching pattern \"$PATTERN\" found."
exit
fi
echo "Waiting for:"
pgrep -l "$PATTERN" "$@"
for PID in $PIDS ; do
while [ -d "/proc/$PID" ] ; do
sleep 1
done
done
fi
exec $NOISE_CMD
引数なしで、すぐに音を出してください。この動作により、便宜上次のようなことが可能になります(alarm.sh
の下でスクリプトを呼び出すとします)。
apt-get upgrade ; ~/bin/alarm.sh
もちろん、alarm.sh
のインスタンスにalarm.sh
のインスタンスを待機させ、他のコマンドを待機させるなど、このようなスクリプトで多くの面白いことができます。または、ログインしている他のユーザーのタスクが完了した直後にコマンドを実行する...>:D
上記のスクリプトの以前のバージョンは、pgrep
への依存を回避し、自分でプロセスIDを検索することに同意する場合は、興味深いかもしれません。
#!/bin/bash
if [ "$#" -lt 2 -o ! -d "/proc/$1" ] ; then
echo "Usage: $(basename "$0") PID COMMAND [ ARGUMENTS... ]"
exit
fi
while [ -d "/proc/$1" ] ; do
sleep 1
done
shift
exec "$@"
少しトピックから外れていますが、同様の状況で役立ちます: reptyr
に興味があるかもしれません。これは、一部の(親)シェルからプロセスを「盗み取り」、現在のシェルから実行するツールですシェル。私は同様の実装を試しましたが、reptyr
は私の目的にとって最もきれいで最も信頼できるものです。