현재 프로세스만 종료하고 셸 파이프라인을 계속하려면 어떻게 해야 합니까?

현재 프로세스만 종료하고 셸 파이프라인을 계속하려면 어떻게 해야 합니까?

Bash에 관해 2가지 관련 질문이 있습니다.

(Q1) 장기 실행 명령(C1)을 사용하여 때때로 일부 출력을 생성하는 장기 실행 명령(C1)을 시뮬레이션하고 처리를 시뮬레이션하는 데 사용되는 명령(C2)을 고려하는 tail -f SomeFile | wc가상 명령줄 C1이 끝나면 출력됩니다. 오랜 시간(평소보다 긴 시간)을 기다린 후 지금까지 어떤 출력이 생성되었는지 확인하고 싶어서 C1을 종료시키고 싶습니다. 그러나 Ctrl-C를 누르면 전체 파이프라인이 종료됩니다.tailwcC1(또는 자체 복합 명령인 경우 C1의 구성 요소)만 종료하려면 어떻게 해야 합니까?
C1이 많은 파일을 반복하고 일부 텍스트를 grep하지만 하나의 파일이 정지된 일부 nfs 서버에서 온 경우 grep 프로세스를 종료하고 싶습니다.

(for F in A B C D E ; do grep sometext $F ; done) | wc

여기서 Ctrl-C는 전체 명령줄을 종료하지만 현재 실행 중인(또는 정지된) 프로세스만 종료하고 나머지 파일 처리를 계속하고 싶습니다.

내가 가진 한 가지 해결책은 새 연결을 열고 ps 출력을 얻은 다음 "종료"하는 것이었습니다. 현재 프로세스만 종료하는 이상한 키 조합과 같은 Bash 자체에 솔루션이 있는지 궁금합니다.

(Q2) 이 질문에 대한 예를 들다가 다음과 같은 명령줄을 만들었고 여기서 Ctrl-C를 누르면 다음과 같은 추가 출력 줄이 나타납니다.

# echo `ping 127.0.0.1` | wc
^C

#

역따옴표(``)를 사용하지 않으면 추가 줄이 나타나지 않습니다.

# tail -f SomeFile | wc
^C
#

백틱(``)은 bash 자체에 의해 처리되고 하위 프로세스가 종료되면 여전히 "빈 출력"으로 간주되어 추가 줄로 인쇄된다고 생각하는 것이 맞습니까?

답변1

그 후에는 bash다음을 실행할 수 있습니다.

cmd1 | cmd2 | (trap '' INT; cmd3)

cmd1Control-C는 및 만 종료 cmd2하지만 은 종료하지 않습니다 cmd3.

예:

$ while sleep .1; do echo -n 1; done | (trap '' INT; tr 1 2)
^C222222222
$ while sleep .1; do echo -n 1; done | tr 1 2
^C

이는 "무시" 신호 처리가 하위 프로세스에 의해 상속된다는 사실을 활용합니다. 이는 명령 trap '' INT에도 영향을 미칩니다 . tr그러나 물론 일부 명령은 자체 SIGINT처리기를 설치하므로 이러한 가정이 깨집니다.

ksh93불행히도 어리석은 실수로 인해 작동하지 않습니다. 해결책은 다음과 같습니다.

ksh93$ while sleep .1; do echo -n 1; done | sh -c 'trap "" INT; exec tr 1 2'
^C222222222ksh93$

답변2

이 명령은 stty -a모든 키보드 단축키를 표시합니다. 매핑된 신호는 Ctrl-C(SIGINT), Ctrl-\(SIGQUIT) 및 Ctrl-Z(SIGSUSP)뿐입니다. 다른 신호에 대한 바인딩은 없습니다.

나는 당신이 명시한 솔루션을 사용할 것입니다. 즉, 종료해야 하는 별도의 셸, ps출력 및 프로세스입니다.kill

두 번째 질문의 경우 악센트(``) 때문이 아니라 echo다음 예를 시도해 보세요.

# echo `sleep 10` | wc
^C

# `sleep 10` | wc
^C
# sleep `echo "10"` | wc
^C
#

답변3

다음 명령을 사용하여 테스트하면 훌륭하게 작동합니다.

tail -f /var/log/kern.log & read -t 10 ;kill $!

위 명령은 10초 동안만 실행된 후 종료됩니다.

관련 정보