관련 응용 프로그램은 DaVinci Resolve입니다. 터미널에서 실행합니다. 닫으면 애플리케이션의 "Socket Disconnected" 메시지가 터미널 출력에 기록됩니다. 그러면 bash 프롬프트가 정상적으로 표시됩니다. 새 명령을 입력하기 시작했는데 갑자기 "소켓 연결 끊김" 터미널에 또 다른 메시지가 나타났습니다. 이것은 내가 입력하는 것을 방해합니다. 다음과 같습니다.
[andrew@unihost ~]$ davinci-resolve
... # Now I exit the application.
Host 'Fusion' Removed
FusionScript Server [37457] Terminated
Socket disconnected
[andrew@unihost ~]$ ls ls Socket disconnected
wtf!!!^C
[andrew@unihost ~]$
비디오 데모:https://youtu.be/arcCOjrN7kw
왜 이런 일이 발생합니까? 이런 일이 발생하지 않도록 하는 방법이 있나요?
내 생각에는 기본 프로세스에 기본 프로세스가 종료된 후에도 지속되는 하위 프로세스가 있는 것 같습니다. 내가 찾았어이것답변. 이게 개발자의 잘못인가요? 이 문제를 어떻게든 해결할 수 있나요(하위 프로세스가 없더라도)?
답변1
예비 설명
davinci-resolve
나는 그것을 전혀 테스트하지 않았습니다. 이 답변은 일반적으로 설계되었습니다.
분석하다
쉘은 davinci-resolve
다시 전경으로 돌아가서 프롬프트를 인쇄하기 전에 종료될 때까지 기다립니다. 분명히, davinci-resolve
메인 프로세스가 종료되고 쉘이 반응한 후, 메인 프로세스의 일부 하위 프로세스(또는 후속 프로세스)가 원치 않는 메시지를 인쇄합니다.
해결책
해결책은 간단할 수 있습니다.
davinci-resolve | cat
요령은 cat
파이프에 쓰는 모든 프로세스가 파이프 끝을 닫을 때까지 종료하지 않는 것입니다. 문제가 있는 자식은 아마도 메인에서 stdout을 상속받아 이를 기다릴 davinci-resolve
것입니다 . cat
일반적으로 이는 원치 않는 메시지가 stderr 또는로 인쇄되는 경우에도 작동합니다 /dev/tty
(즉, 우리 메시지를 우회합니다 cat
). 다른 곳에서 인쇄 중이더라도 아이가 파이프를 열어 두는 것이 중요합니다.
단점도 있습니다:
cat
전체 파이프라인의 종료 상태는 가 아닌 에서 옵니다davinci-resolve
.일부 쉘에서는 다음과 같은 작업을 수행할 수 있습니다..전자는 통과되고 후자는 통과되지 않기 때문에 (및 그 하위 항목)의 stdout 및 stderr은
davinci-resolve
동기화되지 않습니다 .cat
Ctrl+ 경우 c인쇄가 끝나기 전에 다른 프로세스를 종료할 수 있으므로
cat
실제로 보고 싶은 일부 출력을 놓칠 수 있습니다. 또한 문제가 있는 메시지가 stderr에 인쇄되면 아마도 프롬프트를 본 후에 어쨌든 인쇄될 것입니다.+ 면역을 만들 수 있습니다
cat
:Ctrlcdavinci-resolve | sh -c 'trap "" INT; exec cat'
문제가 있는 프로세스는 조기에 종료되거나 표준 출력을 리디렉션할 수 있지만 여전히 표준 오류로 인쇄됩니다. 이 경우에는 기다릴 필요가 없습니다
cat
.문제가 있는 프로세스는 지속되도록 설계되었을 수 있으며 원치 않는 메시지가 프로세스가 종료되었다는 의미는 아닙니다. 이 프로세스가 여전히 존재하고 파이프를 열어둔다면 우리
cat
의 의지도 계속 존재할 것입니다.davinci-resolve
버그가 없는 한 후손이 남을 가능성은 거의 없지만 일반적으로 그런 일이 발생할 수 있습니다.
어떤 이유로 stdout을 전달하고 싶을 수도 있습니다.그리고표준 오류는 통과됩니다 cat
. Immunity cat
+는 여전히 좋은 생각입니다 Ctrl.c
davinci-resolve 2>&1 | sh -c 'trap "" INT; exec cat'
이제 stderr of(및 그 하위 항목)와 stdout을 구별할 수 없으며 davinci-resolve
둘 다 cat
stdout을 전달합니다. 어쨌든 터미널에서 혼합하기를 원하기 때문에 문제가 되지 않습니다. 개별적으로 리디렉션하거나 캡처하려면 설정을 포기하고 처음부터 시작해야 합니다.
문제가 있는 프로세스가 조기에 종료되거나 stdout 및 stderr를 리디렉션하고 원치 않는 메시지를 /dev/tty
(예). 이 상황에서 우리가 할 수 있는 일은 아무것도 없습니다 cat
.
쉘 기능
우리 솔루션을 셸 함수로 구현할 수 있습니다.
davinci-resolve() {
command davinci-resolve "$@" 2>&1 | sh -c 'trap "" INT; exec cat'
}
이 함수는 에 인수 전달을 지원 davinci-resolve
하지만 종료 상태는 프로세스 cat
가 아닌 에서 옵니다(질문이 있는 경우 참조).davinci-resolve
이미 링크가 제공되었습니다.아이디어).
답변2
control-l을 입력하여 화면을 지울 수 있습니다. 이렇게 하면 "소켓 연결 끊김" 메시지가 지워지지만 명령 프롬프트와 부분적으로 작성된 명령은 그대로 유지됩니다. 안타깝게도 davinci-resolve의 출력도 지워지는데, 이는 원하는 작업에 적합할 수도 있고 적합하지 않을 수도 있습니다.
답변3
기본 프로세스가 종료된 직후 "소켓 연결 끊김" 메시지가 나타나면 ; sleep 2
명령에 추가하고 이를 쉘 별칭에 넣을 수 있습니다. 이는 기본적으로 새로운 명령을 바로 입력하지 않도록 상기시키기 위한 방법입니다. 이렇게 하려면 다음을 추가하세요.
alias davinci-resolve="davinci-resolve; sleep 2"
귀하의 .bashrc에
답변4
백그라운드 프로세스는 실제로 쉘을 방해하지 않으며 단지 화면에 낙서를 하고 있을 뿐이며 백그라운드 프로세스의 출력과 쉘이 혼합됩니다.
이 문제를 해결하는 방법에는 여러 가지가 있습니다.
- 파일 리디렉션과 같은 기능을 사용하여 터미널에서 메시지를 삭제 하거나
nohup
파일에 저장할 수 있습니다. - 이 횡설수설을 무시하고 계속 입력하거나, 아무 것도 입력하지 않은 경우 Enter를 누르면 새 프롬프트가 표시됩니다.
- 백그라운드 프로세스에서 보낸 메시지를 읽은 다음 명령줄 편집 키 입력을 사용하여 입력한 내용을 새로 고치고 다시 읽을 수 있게 만들 수 있습니다. 일반 터미널 모드에서는 Ctrl-R이 작업이 수행됩니다. Bash와 같은 다른 많은 응용 프로그램에서는 Ctrl-L화면이 지워지고 프롬프트와 입력한 내용이 다시 인쇄됩니다.
- 전용 창에서 애플리케이션을 실행하고 그래픽 창 시스템의 기능을 사용하여 해당 출력으로 인해 오염되지 않은 다른 창을 열 수 있습니다. :) (이렇게 시끄러운 어플리케이션을 실행시키기 위해 옆에 작은 창을 남겨두었습니다.)
- 애플리케이션을 종료한 후에 이런 일이 발생하고 중지하려는 작업자 스레드가 뒤에 남아 있는 경우
ps -t
터미널에서 현재 실행 중인 항목을 표시하기 위해 해당 스레드를 찾아 종료할 수 있습니다.