如何在已运行的现有命令完成后运行下一个命令?

如何在已运行的现有命令完成后运行下一个命令?

如果我启动一个需要花费很长时间的脚本,我不可避免地会在启动脚本后意识到这一点,并希望在脚本完成后有办法发出某种警报。

例如,如果我运行:

really_long_script.sh

然后按回车键...完成后我如何运行另一个命令?

答案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对我来说,它是最漂亮、最可靠的。

相关内容