如何在已經執行的現有命令完成後執行命令?

如何在已經執行的現有命令完成後執行命令?

如果我啟動一個需要很長時間的腳本,我不可避免地會在啟動腳本後意識到這一點,並希望我有一種方法可以在腳本完成後發出某種警報。

因此,舉例來說,如果我運行:

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

您可以在背景執行腳本(但要注意,腳本輸出 (stdoutstderr) 將繼續轉到您的終端,除非您將其重定向到某個地方),然後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對於我的目的來說,這是最漂亮、最可靠的。

相關內容