¿Cómo ejecutar un comando después de que finaliza uno existente que ya se está ejecutando?

¿Cómo ejecutar un comando después de que finaliza uno existente que ya se está ejecutando?

Si comienzo un guión que va a llevar mucho tiempo, inevitablemente me doy cuenta después de haberlo iniciado y desearía tener una forma de generar algún tipo de alerta una vez que termine.

Entonces, por ejemplo, si ejecuto:

really_long_script.sh

y presione enter... ¿cómo puedo ejecutar otro comando una vez que finalice?

Respuesta1

Puede separar varios comandos por ;, para que se ejecuten secuencialmente, por ejemplo:

really_long_script.sh ; echo Finished

Si desea ejecutar el siguiente programa solo si el script finalizó con el código de retorno 0 (lo que generalmente significa que se ejecutó correctamente), entonces:

really_long_script.sh && echo OK

Si desea lo contrario (es decir, continuar sólo si el comando actual ha fallado), entonces:

really_long_script.sh || echo FAILED

Puede ejecutar su secuencia de comandos en segundo plano (pero tenga cuidado, la salida de las secuencias de comandos ( stdouty stderr) continuará yendo a su terminal a menos que la redirija a alguna parte), y luego wait:

really_long_script.sh &
dosomethingelse
wait; echo Finished

Si ya ejecutó el script, puede suspenderlo con Ctrl-Zy luego ejecutar algo como:

fg ; echo Finished

Donde fgpone el proceso suspendido en primer plano ( bglo haría ejecutarse en segundo plano, más o menos como empezó con &)

Respuesta2

Si el proceso no se ejecuta en el tty actual, intente esto:

watch -g ps -opid -p <pid>; mycommand

Respuesta3

También puedes usar el control de trabajo de bash. si empezaste

$ really_long_script.sh

luego presione ctrl+z para suspenderlo:

^Z
[1]+  Stopped                 really_long_script.sh
$ bg

para reiniciar el trabajo en segundo plano (como si lo hubiera iniciado con really_long_script.sh &). Entonces puedes esperar este trabajo en segundo plano con

$ wait N && echo "Successfully completed"

donde N es el ID del trabajo (probablemente 1 si no ejecutó ningún otro trabajo en segundo plano) que también se muestra como se muestra [1]arriba.

Respuesta4

Hace un tiempo escribí un script para esperar el final de otro proceso. NOISE_CMDpodría ser algo así notify-send ..., dado que DISPLAYestá configurado correctamente.

#!/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

Sin ningún argumento, simplemente haz algo de ruido inmediatamente. Este comportamiento permite algo como esto por conveniencia (digamos que llama al script a continuación alarm.sh):

apt-get upgrade ; ~/bin/alarm.sh

Por supuesto, puedes hacer muchas cosas divertidas con un script de este tipo, como dejar que una instancia de alarm.shespere a una instancia de alarm.sh, que está esperando algún otro comando. O ejecutar un comando justo después de que alguna tarea de otro usuario que haya iniciado sesión haya finalizado... >:D

Una versión anterior del script anterior podría ser interesante si desea evitar una dependencia pgrepy aceptar buscar los ID de los procesos usted mismo:

#!/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 "$@"

Ligeramente fuera de tema, pero útil en situaciones similares: a uno le podría interesarreptyr, una herramienta que "roba" un proceso de algún shell (principal) y lo ejecuta desde el shell actual. He probado implementaciones similares y reptyres la más bonita y confiable para mis propósitos.

información relacionada