여러 명령을 실행하고 bash에서 하나의 명령으로 종료합니다.

여러 명령을 실행하고 bash에서 하나의 명령으로 종료합니다.

하나의 쉘에서 여러 명령(프로세스)을 실행하고 싶습니다. 그들은 모두 멈추지 않는 지속적인 출력을 가지고 있습니다. 백그라운드에서 실행하면 중단 됩니다 Ctrl. - 를 사용하여 모든 프로세스를 중지 C할 수 있도록 단일 프로세스(아마도 서브셸?)로 실행하고 싶습니다 .CtrlC

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

백그라운드( &)에서 프로세스를 실행하여 이를 수행할 수 있지만 프로세스를 포그라운드로 가져와 중지해야 합니다. 프로세스를 래핑하고 프로세스를 중지하면 "하위 프로세스"가 중지됩니다.

답변1

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

~$ 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

이것은 백그라운드와 command1포그라운드에서 실행되므로 +를 사용하여 죽일 수 있습니다. command2command3CtrlC

Ctrl+를 사용하여 마지막 프로세스를 종료하면 명령 실행이 +를 눌러 전송 되는 인터럽트 신호 수신과 연결되므로 C명령이 실행됩니다 .kill %1; kill %2CtrlC

첫 번째 및 두 번째 백그라운드 프로세스(귀하 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] /'

물론 구경하셔도 됩니다화면. 필요에 따라 콘솔을 여러 개의 개별 콘솔로 분할할 수 있습니다. 따라서 모든 명령을 동시에 개별적으로 모니터링할 수 있습니다.

답변2

동일한 프로세스에서 실행되도록 예약하고 해당 프로세스만 실행하도록 예약하면 한 번에 여러 프로세스를 쉽게 종료할 수 있습니다.프로세스 그룹.

Linux는 유틸리티를 제공합니다setsid새 프로세스 그룹에서 프로그램을 실행합니다(또는 새 세션에서도 실행되지만 우리는 그것에 대해 신경쓰지 않습니다). (이것은작동하지만 더 복잡함아니요setsid )

프로세스 그룹의 프로세스 그룹 ID(PGID)는 그룹에 있는 원래 상위 프로세스의 프로세스 ID입니다. 프로세스 그룹의 모든 프로세스를 종료하려면 음수 PGID를 kill시스템 호출 또는 명령에 전달하십시오. 해당 PID가 있는 원래 프로세스가 종료되더라도 PGID는 유효한 상태로 유지됩니다(다소 혼란스러울 수 있음).

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

답변3

아직 나오지 않은게 놀랍지만 제가 가장 좋아하는 방법은서브쉘백그라운드 명령으로. 용법:

(command1 & command2 & command3)

두 가지 모두의 출력이 표시되고 모든 bash 명령과 편의 기능을 계속 사용할 수 있으며 단일 명령으로 Ctrl-c모두 종료할 수 있습니다. 저는 보통 이것을 사용하여 라이브 디버깅 클라이언트 파일 서버와 백엔드 서버를 모두 시작하므로 필요한 경우 쉽게 종료할 수 있습니다.

작동 방식은 command1command2하위 쉘 인스턴스의 배경과 해당 인스턴스의 전경에서 실행되고 하위 쉘은 키 누르기로부터 종료 신호를 command3가장 먼저 수신하는 것입니다 . Ctrl-c이는 누가 어떤 프로세스를 소유하고 언제 데몬이 종료되는지 측면에서 bash 스크립트를 실행하는 것과 매우 유사합니다.

답변4

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

1st command | 2nd command | 3rd command

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

관련 정보