bash에 두 개의 동시 명령이있는 Ctrl-C


15

Linux 컴퓨터의 bash에서 두 명령을 동시에 실행하고 싶습니다. 따라서 내 ./execute.shbash 스크립트에서 나는 다음을 넣었다.

command 1 & command 2
echo "done"

그러나 bash 스크립트를 중지하고 Ctrl+ C를 누르면 두 번째 명령 만 중지됩니다. 첫 번째 명령은 계속 실행됩니다. 전체 bash 스크립트가 중지되었는지 어떻게 확인합니까? 또는 어쨌든 두 명령을 어떻게 중지합니까? 이 경우 얼마나 자주 Ctrl+를 누르더라도 C명령이 계속 실행되고 터미널을 닫아야합니다.


후속 질문을 별도의 질문으로 만들고 여기서 제거하십시오. 이제 두 질문에 모두 답이되었는지 아니면 초기 질문에 대한 것인지는 분명하지 않습니다.
젤다

답변:


17

입력하면

command 1 & command 2

이것은 같다

command 1 &
command 2

즉, 백그라운드에서 첫 번째 명령을 실행 한 다음 포 그라운드에서 두 번째 명령을 실행합니다. 특히 이것은 여전히 실행중인 경우에도 완료 echo "done"후 인쇄 됩니다.command 2command 1

아마 원하는

command 1 &
command 2 &
wait
echo "done"

백그라운드에서 두 명령을 모두 실행하고 두 명령이 완료 될 때까지 기다립니다.


CTRL-C를 누르면 SIGINT 신호를 전경 프로세스, 즉 command 2버전 또는 wait내 버전으로 만 보냅니다 .

다음과 같이 트랩을 설정하는 것이 좋습니다.

#!/bin/bash

trap killgroup SIGINT

killgroup(){
  echo killing...
  kill 0
}

loop(){
  echo $1
  sleep $1
  loop $1
}

loop 1 &
loop 2 &
wait

트랩을 사용하면 CTRL-C에 의해 생성 된 SIGINT 신호가 트랩되어 killgroup함수 로 대체되어 모든 프로세스가 종료됩니다.


답변 주셔서 감사합니다! 그러나 후속 질문이 있습니다. 이제 다음 스크립트가 있습니다. trap killgroup SIGINT killgroup () {echo killing ... kill 0} command001 command1 & command2 command2가 완료되면 스크립트를 계속 사용할 수 있기 때문에 대기 명령을 생략했습니다. 그러나 스크립트를 실행할 때 명령 1이 이미 시작된 것 같습니다. 이 문제를 해결할 수 있습니까? 감사합니다
maero21

command001이 완료된 후 바로 command1이 시작됩니다. set -x스크립트 시작 부분에서 사용 하여 실행되는 명령을 인쇄 할 수 있습니다 .
michas

6

스크립트에서 백그라운드로 명령을 넣을 때 PID가 화면에 표시되지 않습니다. $!마지막 프로세스의 PID를 저장 하는 내장 변수 를 사용하여 command1의 PID를 캡처 할 수 있습니다.

command1 &
echo $!

command1의 PID를 에코합니다.

Bash는 또한 특정 신호가 수신 될 때 실행할 일련의 명령을 등록하는 데 사용할 수있는 트랩 내장 기능을 제공합니다. 메인 스크립트를 종료하기 전에 이것을 사용하여 SIGINT 및 kill command1을 잡을 수 있습니다.

#!/bin/bash

onINT() {
echo "Killing command1 $command1PID too"
kill -INT "$command1PID"
exit
}

trap "onINT" SIGINT
command1 &
command1PID="$!"
comamnd2
echo Done

이제 명령 2가 실행되는 동안 타격 Ctrl C하면 command1과 command2가 모두 SIGINT로 전송됩니다.


%n이 쉘에서 구문을 사용 하여 특정 백그라운드 작업을 종료 할 수도 있습니다 . 일반적으로 kill %1가장 최근의 유일한 백그라운드 프로세스를 종료하기 위해 발행 합니다. 더 많은 백그라운드 프로세스가 있으면 jobs먼저 목록을 보는 데 사용 하십시오.
9000

@ 9000 : 예. 그러나 OP가 스크립트 (./execute.sh)에서 명령을 실행하고 있으므로 작업을 수행하는 것이 훨씬 더 문제가 있습니까?

@lain : 물론입니다. 나는 스크립트에서 실행에 대한 요점을 놓쳤다.
9000

5

최신 버전의 GNU Parallel은 원하는 작업을 수행합니다.

parallel ::: "command 1" "command 2"
echo "done"

또는 command동일하게 유지되는 경우 :

parallel command ::: 1 2
echo done

빠른 소개를 위해 소개 동영상을 시청하십시오. https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

튜토리얼을 진행하십시오 (man parallel_tutorial). 당신은 그것을 사랑하는 명령 줄입니다.


1

Ctrl+ C는 SIGINT 신호를 프론트 프로세스로 보냅니다 command2. command1백그라운드에서 실행되므로 입력 스트림과 관련이 없습니다.

command1 &bash 를 입력하면 다음과 같은 프로세스 PID를 제공해야합니다 [1234]. 이 프로세스를 종료하려면을 사용할 수 있습니다 kill 1234. 이제 둘 모두의 PID가 command1있고 command2(을 살펴보십시오 ps -ef) kill모두 사용 하여 종료 할 수 있습니다 .

kill pid1 pid2 pid3 ...

약간의 트릭은 백그라운드에서 두 명령을 모두 실행하는 것입니다.

command1 & command2 &

Bash는 죽일 준비가 된 두 PID를 제공합니다. 또 다른 트릭은 command1일단 죽이면 포 그라운드로 돌아 오는 것입니다 command2.

command1 & command2
# Hit Ctrl+C : command2 terminates.

fg # Bring back command1 to foreground.
# Hit Ctrl+C again, command1 terminates.

더 많은 정보는 여기에 있습니다 : http://linuxg.net/how-to-manage-background-and-foreground-processes/

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