git
나는 가끔 관심 있는 변화를 찾기 위해 곡괭이 기능을 사용합니다 . 분명히 이것은 매우 느릴 수 있지만(예를 들어 에도 동일하게 적용됨 hg grep
), 더 중요하게는 폭발적입니다. 일부 결과는 함께 클러스터링되고 비활성으로 분리됩니다.
이러한 이유로 나는 실제로 출력을 다음으로 파이프하여 결과를 읽으려고 합니다 less
(실제로 이것이 기본적으로 수행되는 작업입니다 ). git
버스트가 발생하면ctrl-S
소프트웨어 프로세스가 충분히 빨라질 수 없습니다. 이제 컨트롤이 유용해졌습니다.
그러나 나는 종종 이런 동작에 직면합니다. less
충분히 멀리 스크롤하면 화면에 표시할 콘텐츠의 한 줄만 명령에서 나오지 않더라도 명령이 중단되고 더 많은 메시지가 나올 때까지 프롬프트와 대부분의 제어를 잃게 됩니다 git
. less
온다. 이제 왜 이런 일이 발생하는지 이해하지만이것이 쉘 명령의 동작이라면 ctrl-Z
프롬프트를 복원하고 실행하는 데 사용할 것입니다 bg
. less
호출기 경고를 복원하는 동등한 방법이 있습니까 ?
이 경우에는 ctrl-Z
소용이 없습니다. Unix 작업 제어는 화면 내용을 관리하는 명령에 적합하지 않습니다. 또한 어쨌든 나는 쉘 프롬프트로 돌아가고 싶지 않습니다. 일반적으로 내가 원하는 것은 스페이스바를 반복적으로 누르는 동안 내가 본 것이 무엇인지 확인하는 것이므로 더 적은 것을 남기고 싶지 않습니다.
Ctrl-C
또한 쓸모가 없습니다. 프롬프트를 다시 시작할 수는 있지만 수신된 콘텐츠가 정지될 수도 있습니다. 즉, 호기심이 충족되어 최신 콘텐츠로 돌아가려고 할 때(스페이스바를 몇 번 누르는 등 G
) ) , 아무리 기다려도 보이는 것만 나타납니다. F
( 모드)를 사용해도 마찬가지입니다 tail -f
.
이 명령을 사용하여 git
동작을 시뮬레이션합니다.
(echo -e 'foo\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.' ; sleep 3 ; echo -e 'bar\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.' ; sleep 10; echo baz) | less
답변1
해결책은 실제로 를 사용하는 것이지만 ctrl-C
생성된 신호가 다음과 같은지 확인하는 것입니다.아니요에 파이프된 다른 명령으로 전송됩니다 less
. 처음에 얻지 못한 결정적인 통찰력은 다음과 같습니다. less
읽기는 터미널에서만 수행되므로 일반 입력은 해당 명령에만 사용할 수 있는 반면, 터미널 드라이버에서 발생하는 신호는 파이프의 모든 프로세스로 전달됩니다.
이러한 방식으로 신호 전달을 제어하는 것은 말처럼 쉽지 않습니다. 내가 아는 한 좋은 해결책은 없으므로 가장 덜 나쁜 해결책을 생각해 냈습니다. 즉, setsid(1)
다른 명령을 자체 세션으로 격리하는 것입니다.
% setsid sh -c "/bin/echo -e 'foo\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.' ; sleep 3 ; /bin/echo -e 'bar\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.' ; sleep 10; /bin/echo baz" sh-c | less
이 설정을 사용하면 클릭할 때 ctrl-C
예상되는 동작을 얻을 수 있습니다 . less
이전에 수신할 수 있었던 콘텐츠 뒤에 프롬프트가 나타나고 sleep
모든 이전 콘텐츠를 다시 찾아볼 수 있으며 최신 콘텐츠로 직접 돌아가면 마지막 콘텐츠( baz
, 여기 )가 결국 나타납니다. 콘텐츠 생성을 자체 세션에 채워 신호에서 프로세스를 분리합니다(읽기 작업을 중단하기 위해 포함해야 합니다. 그렇지 않으면 읽기 작업이 less
중단됩니다).
주요 문제는 이것이 setsid(1)
완전히 비표준이라는 것입니다. 모든 Unix 및 Unix 계열 커널은 setsid(2)
시스템 호출을 지원하지만 독립형 명령으로서의 가용성은 약간 Linux주의입니다. 설치에서 사용할 수 없는 경우 선호하는 패키지 관리자가 이를 별도로 또는 패키지의 일부로 제공해야 합니다(소스는 단순하고 공개 도메인에 있음) util-linux
.
% brew install util-linux # MacOS
이름 때문에 오해하지 마십시오. setsid(1)
적어도 이식 가능합니다. (참고: util-linux
여기에 표시된 Homebrew의 통에는 통만 포함되어 있습니다. 즉, 충돌로 인해 검색 경로에 아무것도 설치되지 않았습니다. bin 디렉터리를 수동으로 추가해야 합니다. $PATH
)