여러 명령을 실행하고 bash에서 하나로 죽입니다.


51

단일 쉘에서 여러 명령 (프로세스)을 실행하고 싶습니다. 그들 모두는 연속 출력을 가지고 있으며 멈추지 않습니다. 배경 나누기를 실행 Ctrl- C. Ctrl- 를 사용하여 모든 프로세스를 중지 할 수 있도록 단일 프로세스 (서브 셸, 어쩌면?)로 실행하고 싶습니다 C.

구체적으로 말하면 mocha(감시 모드)로 단위 테스트를 실행하고 서버를 실행하고 파일 사전 처리 (감시 모드)를 실행하고 하나의 터미널 창에서 각각의 출력을 확인 하고 싶습니다 . 기본적으로 일부 작업 러너를 사용하지 않으려 고합니다.

백그라운드에서 프로세스를 실행하여이를 실현할 수 &있지만 ( ) 프로세스 를 중지하려면 프로세스를 포 그라운드로 넣어야합니다. 나는 그들을 감싸는 프로세스를 갖고 싶습니다. 프로세스를 중지하면 '자식'이 중지됩니다.


그들은 동시에 또는 차례로 실행해야합니까?
Minix

예, 프로세스가 동시에 실행되어야하지만 각각의 결과를 확인해야합니다.
user1876909

답변:


67

명령을 동시에 실행하려면 &명령 구분 기호를 사용할 수 있습니다 .

~$ command1 & command2 & command3

이 시작 command1되고 백그라운드에서 실행됩니다. 와 동일합니다 command2. 그런 다음 command3정상적으로 시작 됩니다.

모든 명령의 출력이 함께 왜곡되지만 문제가되지 않으면 해결 방법이됩니다.

나중에 출력을 개별적으로 살펴 보려면 각 명령의 출력을로 파이프하여 출력 tee을 미러링 할 파일을 지정할 수 있습니다.

~$ command1 | tee 1.log & command2 | tee 2.log & command3 | tee 3.log

출력이 매우 지저분 할 수 있습니다. 이를 방지하기 위해 모든 명령의 출력에 접두사를 제공 할 수 sed있습니다.

~$ echo 'Output of command 1' | sed -e 's/^/[Command1] /' 
[Command1] Output of command 1

그래서 우리가 그 모든 것을 합치면 우리는 다음을 얻습니다.

~$ command1 | tee 1.log | sed -e 's/^/[Command1] /' & command2 | tee 2.log | sed -e 's/^/[Command2] /' & command3 | tee 3.log | sed -e 's/^/[Command3] /'
[Command1] Starting command1
[Command2] Starting command2
[Command1] Finished
[Command3] Starting command3

이것은 아마도 당신이 볼 것의 가장 이상적인 버전입니다. 그러나 지금 내가 생각할 수있는 최선의 방법.

한 번에 모두 중지하려면 빌드를 사용할 수 있습니다 trap.

~$ trap 'kill %1; kill %2' SIGINT
~$ command1 & command2 & command3

이 실행됩니다 command1command2배경과 command3당신이 그것을 죽일 수 전경에 Ctrl+ C.

Ctrl+로 마지막 프로세스를 종료 C하면 kill %1; kill %2명령이 실행됩니다. 우리는 실행을 INTerupt SIGnal의 수신과 연결했기 때문에 Ctrl+ 를 누릅니다 C.

그들은 각각 첫 번째와 두 번째 백그라운드 프로세스를 종료합니다 (your command1command2). 를 사용하여 명령을 완료 한 후에 트랩을 제거하는 것을 잊지 마십시오 trap - SIGINT.

명령의 완전한 괴물 :

~$ trap 'kill %1; kill %2' SIGINT
~$ command1 | tee 1.log | sed -e 's/^/[Command1] /' & command2 | tee 2.log | sed -e 's/^/[Command2] /' & command3 | tee 3.log | sed -e 's/^/[Command3] /'

물론 screen을 볼 수 있습니다 . 콘솔을 원하는만큼 별도의 콘솔로 분할 할 수 있습니다. 따라서 모든 명령을 개별적으로 동시에 모니터링 할 수 있습니다.


3
모든 비판을 기대합니다. :)
Minix

2
감사합니다. 내가 원하는 것을 정확하게 수행합니다 (트랩 명령). 솔루션은 재사용 성을 위해 스크립트로 싸야합니다.
user1876909 2016 년

@ user1876909 여기에 스켈레톤이 있습니다. 구체적인 사항은 귀하에게 달려 있습니다 [1]. 기꺼이 도와 드리겠습니다. [1] pastebin.com/jKhtwF40
Minix

3
이것은 오히려 영리 솔루션, IV는 +1 뭔가 새로운, 브라보를 배웠다
마이크-m

1
이것은 놀랍다. 나는이 답변을 파고 배울 수있는 많은 것을 가지고 있습니다.
ccnokes

20

동일한 프로세스 그룹 에서 프로세스 를 실행하도록 정렬하면 여러 프로세스를 한 번에 쉽게 종료 할 수 있습니다 .

리눅스는 setsid새로운 프로세스 그룹에서 프로그램을 실행할 수있는 유틸리티 를 제공합니다 (새 세션에서도). (이것은 가능 하지만 없이는 더 복잡setsid 합니다.)

프로세스 그룹의 PGID (프로세스 그룹 ID)는 그룹에서 원래 상위 프로세스의 프로세스 ID입니다. 프로세스 그룹에서 모든 프로세스를 종료하려면 PGID의 음수를 kill시스템 호출 또는 명령에 전달하십시오. PGID는이 PID를 사용하는 원래 프로세스가 종료 되더라도 유효합니다 (약간 혼동 될 수 있음).

setsid sh -c 'command1 & command2 & command3' &
pgid=$!
echo "Background tasks are running in process group $pgid, kill with kill -TERM -$pgid"

비 대화식 쉘 에서 백그라운드로 프로세스를 실행 하면 모두 프로세스가 쉘의 프로세스 그룹에 남아있게됩니다. 백그라운드 프로세스가 자체 프로세스 그룹에서 실행되는 것은 대화식 셸에만 있습니다. 따라서 포 그라운드에 남아있는 비 대화식 쉘에서 명령을 포크하면 Ctrl+ C가 명령을 모두 종료합니다. 사용 wait쉘이 종료하는 모든 명령을 기다릴 수 있도록 내장을.

sh -c 'command1 & command2 & command3 & wait'
# Press Ctrl+C to kill them all

2
순차 답변 (하단의 방법). 이해하고 암기하는 것이 간단합니다.
니콜라스 마샬

14

나는 이것이 아직 여기에 놀랐지 만, 이것을하는 가장 좋아하는 방법은 배경 명령과 함께 서브 쉘 을 사용하는 것입니다 . 용법:

(command1 & command2 & command3)

출력은 모든 bash 명령과 편의 기능을 여전히 사용할 수 있으며 단일 항목 Ctrl-c으로 모두 종료됩니다. 나는 보통 이것을 사용하여 실시간 디버깅 클라이언트 파일 서버와 백엔드 서버를 동시에 시작하므로 원할 때 쉽게 죽일 수 있습니다.

이 작동하는 방식은입니다 command1command2새로운 서브 쉘 인스턴스의 백그라운드에서 실행되며, command3해당 인스턴스의 전경이며, 서브 쉘은 처음부터 킬 (kill) 신호를 수신 무엇 Ctrl-c키 누름. 누가 어떤 프로세스를 소유하고 백그라운드 프로그램이 언제 종료되는지에 관해 bash 스크립트를 실행하는 것과 매우 유사합니다.


wait최종 명령 (예 : command3)으로 추가 하면 사용자가 Ctrl-c를 누른 후 정리 코드를 실행할 수 있습니다 .
dotnetCarpenter

0

세미콜론을 사용 ;하거나 다음 &&과 같이 사용할 수 있습니다 .

cmd1; cmd2   # Runs both the commands, even if the first one exits with a non-zero status.

cmd1 && cmd2 # Only runs the second command if the first one was successful.

그것은 명령을 동시에 실행하지 않습니다.
Gilles 'SO- 악마 중지

-2

을 사용할 수 있습니다 pipe. 파이프의 양쪽 끝에서 동시에 명령이 시작됩니다. 또한 모든 명령을 중지 할 수 있어야합니다 CTRL-C.

1st command | 2nd command | 3rd command

명령을 차례대로 실행하려면 @serenesat의 방법을 사용할 수 있습니다.


이것은 첫 번째 명령의 출력을 두 번째 명령으로 전달하는 등의 작업으로, 첫 번째 명령의 출력이 터미널에서 끝나기 때문에 여기서는 적합하지 않습니다.
Gilles 'SO- 악마 중지
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.