이미 실행중인 기존 명령이 완료된 후 명령을 실행하는 방법은 무엇입니까?


32

오랜 시간이 걸리는 스크립트를 시작하면 스크립트를 시작한 후에 필연적으로이를 인식하고 스크립트가 완료되면 일종의 경고를 수행 할 수있는 방법이 있었으면합니다.

예를 들어 내가 실행하면 :

really_long_script.sh

Enter 키를 누릅니다 ... 완료되면 다른 명령을 어떻게 실행할 수 있습니까?

답변:


45

로 여러 명령을 구분할 수 있으므로 다음과 같이 ;순차적으로 실행됩니다.

really_long_script.sh ; echo Finished

스크립트가 return-code 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할 것이 시작 거의 같은 백그라운드에서 실행 &)


@mlissner는이 사건을 다루 내 대답을 확장
올란드

8
fg재개 한 작업의 값을 리턴 하므로 fg && echo Finished다른 명령을 실행하기 전에 명령이 성공하도록하려면 사용할 수 있습니다 .
palswim 2016 년

13

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]위와 같이 표시됩니다 .


11

프로세스가 현재 tty에서 실행되지 않으면 다음을 시도하십시오.

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

2
의 창조적 인 사용을 좋아합니다 watch. 초소형 답변과 시계를 사용하는 새로운 유용한 방법 배우기
Piotr Czapla

2

기존 명령이 실행되는 동안 창에 다음 명령을 입력하고 Enter 키를 누르면 첫 번째 명령이 완료되면 두 번째 명령이 자동으로 실행됩니다.

더 우아한 방법이 있다고 생각하지만 이것이 효과가있는 것 같습니다.

명령이 완료된 후 경보를 실행하려는 경우 .bashrc에서 이러한 별명을 작성한 후 실행 alert중에 실행할 수 있음을 추가하는 편집

 alias alert_helper='history|tail -n1|sed -e "s/^\s*[0-9]\+\s*//" -e "s/;\s*alert$//"'
 alias alert='notify-send -i gnome-terminal "Finished Terminal Job" "[$?] $(alert_helper)"'

7
실행중인 스크립트가 한 시점에서 입력을 기대하지 않는 한.
Daniel Beck

@ 다니엘-그래 ... 문제입니다. 사격.
mlissner

1

얼마 전에 다른 프로세스가 끝날 때까지 기다리는 스크립트를 작성했습니다. 올바르게 설정되어 있다면 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일부 (부모) 쉘에서 프로세스를 "훔치고"현재 쉘에서 실행하는 도구 인에 관심이있을 수 있습니다 . 나는 비슷한 구현을 시도 reptyr했으며 내 목적에 가장 아름답고 신뢰할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.