Как выполнить команду после завершения уже работающей?

Как выполнить команду после завершения уже работающей?

Если я начинаю сценарий, выполнение которого займет много времени, я неизбежно это осознаю уже после того, как начну его выполнять, и мне хотелось бы иметь возможность как-то оповестить об этом, когда он закончится.

Так, например, если я запущу:

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 — идентификатор задания (вероятно, 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и согласиться на поиск идентификаторов процессов самостоятельно:

#!/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это самая красивая и надежная для моих целей.

Связанный контент