![如何在已經執行的現有命令完成後執行命令?](https://rvso.com/image/1289035/%E5%A6%82%E4%BD%95%E5%9C%A8%E5%B7%B2%E7%B6%93%E5%9F%B7%E8%A1%8C%E7%9A%84%E7%8F%BE%E6%9C%89%E5%91%BD%E4%BB%A4%E5%AE%8C%E6%88%90%E5%BE%8C%E5%9F%B7%E8%A1%8C%E5%91%BD%E4%BB%A4%EF%BC%9F.png)
如果我啟動一個需要很長時間的腳本,我不可避免地會在啟動腳本後意識到這一點,並希望我有一種方法可以在腳本完成後發出某種警報。
因此,舉例來說,如果我運行:
really_long_script.sh
然後按 Enter...完成後如何執行另一個指令?
答案1
您可以使用 分隔多個命令;
,以便它們按順序執行,例如:
really_long_script.sh ; echo Finished
如果您希望僅在腳本以返回碼 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
將使其在後台運行,非常類似於開始&
)
答案2
如果該進程不在目前 tty 上運行,請嘗試以下操作:
watch -g ps -opid -p <pid>; mycommand
答案3
您也可以使用 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]
。
答案4
不久前我寫了一個腳本來等待另一個行程的結束。假設設定正確,NOISE_CMD
可能類似於。notify-send ...
DISPLAY
#!/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
,一種從某個(父)shell 中「竊取」進程並從目前 shell 中運行它的工具。我嘗試過類似的實現,reptyr
對於我的目的來說,這是最漂亮、最可靠的。