*모든* 프로세스가 시작될 때 터미널에 PID를 인쇄하는 방법은 무엇입니까?

*모든* 프로세스가 시작될 때 터미널에 PID를 인쇄하는 방법은 무엇입니까?

내가 시작하면비동기식("백그라운드") 프로세스에서는 새 프로세스의 PID를 포함한 일부 정보가 프로세스가 실행되기 전에 터미널에 인쇄됩니다. 예를 들어

$ sleep 3 &
[1] 8217
$ 
[1]  + done       sleep 3
$ 

이러한 정보(특히 PID)를 시작 부분에 인쇄할 수 있는 방법이 있습니까?모든비동기적으로 시작되는 프로세스뿐만 아니라 프로세스도 마찬가지입니까?


배경

이것을 원하는 이유는 일상적인 작업 환경의 특성으로 인해 다음과 같은 일이 자주 발생하기 때문입니다.동기식장기 실행 프로세스가 에 응답하지 않습니다 Ctrl-C. (항상 이러한 프로세스를 "장기 실행"으로 만드는 이유는 내가 예상했던 것보다 훨씬 더 많은 출력을 생성한다는 것입니다.) 이러한 프로세스를 중지하는 가장 확실한 방법은 kill -9다른 창에서 실행하는 것입니다. 이를 위해 PID를 쉽게 사용할 수 있습니다.

Ctrl-Z업데이트: 내 원래 게시물에서는 이것이 옵션이 아니라는 점을 언급하지 않았습니다 . (저는 Emacs에서 실행되는 쉘에서 작업 중이므로 Ctrl-ZEmacs를 일시 중지합니다.)

답변1

처럼스티븐 키트가 설명합니다., zsh에서 PID를 인쇄하는 것은 다소 어려울 것입니다. 하지만 다른 방법으로도 정보를 얻을 수 있습니다.

Ctrl+를 눌러 Z프로세스를 일시 중지하면 zsh가 해당 PID를 표시합니다. 그리고 죽이고 싶다면 먼저 Ctrl+를 눌러 C직접 죽이세요. Ctrl+가 C실패 하면 "더 어려운" 종료를 위해 Ctrl+를 시도합니다( + 는 일반적으로 프로그램에 현재 작업을 중지하고 제어권을 사용자에게 돌려주라고 지시하는 SIGINT를 보냅니다. + 는 일반적으로 프로그램에 하드 충돌을 지시하는 SIGQUIT를 보냅니다). Emacs 내에서도 이 작업을 수행할 수 있습니다. 쉘 모드에서 키를 눌러 터미널로 전달하고 , 전달하고 , 전달합니다 . Term 모드에서는 및 가 직접 전달되지만 단일 .\CtrlCCtrl\C-c C-zC-zC-c C-cC-cC-c C-\C-\C-zC-\C-c C-cC-c

프로세스가 터미널 설정을 변경하거나 신호를 차단하는 경우 종료할 위치를 찾는 편리한 방법은 터미널을 이용하는 것입니다. 터미널이 무엇인지 알아보세요. tty터미널 내부의 명령을 사용하여 이 작업을 수행할 수 있습니다 . 이 부분을 프롬프트나 터미널 제목의 일부로 만들 수 있습니다(저는 터미널 제목에 넣었습니다). Emacs는 터미널 제목을 표시하지 않지만 다음 표현식을 평가하여 정보에 대한 액세스를 제공합니다.

(process-tty-name (get-buffer-process (current-buffer)))

쉘 모드를 포함한 대부분의 모드에서 표현식을 평가하려면 M-:표현식을 입력한 후 입력하십시오. 용어 모드에서 C-c M-x eval-expression RET표현식을 입력한 후 입력하세요. 이것을 자주 사용하는 경우 다음 명령을 관련 모드의 키에 바인딩하십시오.

(defun buffer-process-tty-name ()
  (interactive)
  (let ((tty (process-tty-name (get-buffer-process (current-buffer)))))
    (if (interactivep) (message "%s" tty))
    tty))

터미널 이름을 알고 나면 예를 들어 ps -t pts/42또는 를 사용하여 pgrep -t pts/42해당 터미널에 연결된 프로세스를 나열할 수 있습니다.

답변2

이 정보를 로그로 남길 수 있는 방법은 없는 것 같고, 좀 더 자세히 살펴보면 제대로 설계하기 어려울 것 같습니다(저도 처음에는 구현하기 어려울 거라 생각했는데,일까츄그 문제를 해결했습니다).

구현 문제는 정보를 올바른 위치에 기록하는 것이라고 생각했습니다. 쉘이 하위 항목을 시작할 때 하위 항목을 분기한 다음 실행합니다(자기 자신을 하위 항목으로 대체할 수 없는 경우에는 분기하지 않습니다). 분기되면 프로세스가 복제됩니다. 복사본 중 하나는 호출에서 반환 코드 0을 가져오며 fork()이는 자식임을 나타내며 다른 복사본은 자식의 프로세스 식별자를 가져오며 이는 부모임을 나타냅니다. 자식은 부모의 파일 설명자를 상속하므로 에 대한 설정을 하기 전에 자신의 pid를 기록할 수 있습니다 exec().

디자인 문제는 무엇을 기록할지 선택하는 것입니다. 셸에서 시작된 모든 프로세스를 기록하면 불필요한 로그가 많이 남게 됩니다.예를 들어프롬프트 구성과 관련된 프로세스에 대해! "실제" 명령의 경우에도 파이프라인 및 기타 복합 명령에 대해 무엇을 기록할지 결정해야 합니다. 그런 다음 일관성을 위해 내장 명령 또는 셸이 대체되는 상황에 대해 기록할 내용을 찾아야 합니다. (수동으로 하지 않는 한 대화형 쉘에서는 그런 일이 일어날 수 없다고 생각하지만 exec).

이에 대해 더 자세히 알아보려면 addproc()및 및 printjobs()를 확인 하세요 .jobs.czexecve()exec.c

관련 정보