너무 길어요.

너무 길어요.

이것은 vim을 미치게 만듭니다:

$strace -o >(vim -; stty sane) file.out; stty sane

stty sane처리된 대체 항목과 다음 명령을 입력했지만 둘 다 작업을 수행하지 않았습니다. strace 명령을 vim에 파이프하자마자 vim이 더 이상 올바르게 작동하지 않습니다. (vim이 stdinstrace에 대한 출력만 허용하고 제공 할 수 있다는 것을 알고 있지만 stderr-o플래그는 무엇을 합니까?) 도움이 필요하십니까?

답변1

너무 길어요.

strace -o '|vim -' file.out

~에 대한-o

-ostdout 또는 stderr와는 다른 추가 출력 채널을 제공하기 위해 존재합니다. -o strace명령의 표준 오류이기도 한 표준 오류에는 아무것도 인쇄되지 않습니다( file.out귀하의 경우). -o이를 가능하게 하려면 두 스트림을 분리할 수 있으면 좋을 것입니다 .


질문

귀하의 접근 방식에 결함이 있고 귀하가 상상했던 것과 다르다는 것은 도움이 되지 않습니다 stty sane. 다음 명령을 반복하겠습니다.

strace -o >(vim -; stty sane) file.out; stty sane

여기에는 두 가지 일반적인 문제가 있습니다.

  1. 작업 제어가 활성화되면 개념이 나타납니다.포그라운드 프로세스 그룹. 언제든지 단말기는 전경에 있는 그룹을 인식합니다. 포그라운드 프로세스 그룹에 속하지 않는 프로세스는 공식적으로 백그라운드에 있습니다.

백그라운드 프로세스는 제어 터미널에서 데이터를 읽을 수 없습니다. SIGTTIN시도하면 데이터를 수신합니다. 이 신호는 프로세스가 이를 무시하거나 다르게 처리하지 않는 한 이를 차단합니다.

백그라운드 프로세스는 제어 터미널에 쓸 수 있지만 시도하고 stty tostop활성화되면 프로세스가 SIGTTOU신호를 무시하거나 다르게 처리하지 않는 한 신호를 수신합니다. 중지되지 않으면 tostop프로세스는 신호에도 불구하고 여전히 터미널에 쓸 수 있습니다.

위의 메커니즘은 백그라운드 프로세스가 터미널에서 입력을 훔치는 것을 방지하지만 터미널에 계속 연결된 상태를 유지하여 포그라운드로 가져와 조작할 수 있도록 합니다.그 다음에터미널에서 읽습니다. 이는 프로세스를 시작하는 터미널에 유용합니다. 다른 터미널과의 가능한 상호 작용은 포그라운드 또는 백그라운드에 있는 것과 아무 관련이 없으며 다른 터미널은 어쨌든 "외부"입니다. 따라서 프로세스는 충분한 권한이 있는 한 제어 터미널이 아닌 터미널에서 읽거나 쓸 수 있습니다. .

귀하의 경우 처음에는 포그라운드 프로세스 그룹이 셸과 연결된 다음 ; 과 (외부); 마지막으로 다시 셸과 관련된 stracestty입니다 >().

Bash 내부의 프로세스는 >()프로세스에 할당됩니다 . >()이는 (외부) 프로세스가 완료되고 쉘의 프로세스 그룹이 포그라운드로 가져온 vim후에만 터미널에서 데이터를 읽을 수 있음 을 의미합니다. 이로 인해 두 번째 문제가 발생합니다.stracestty>()

  1. vim최종적으로 터미널에서 읽을 수 있게 되면 쉘도 읽기를 시도합니다. 다음 두 가지를 비교하십시오.
  • strace -o >(vim -) true

    커서를 이동합니다. 일부 입력은 쉘로 이동 vim하고 일부 입력은 쉘로 이동합니다. 그들은 모두 프론트 데스크에 있습니다.

  • strace -o >(vim -) true; sleep 1000

    커서를 움직여 보세요. 지금은 sleep전경에 있기 때문에 다릅니다 . + sleep로 종료하면 동작이 변경됩니다.CtrlC

어떤 경우든 vim다른 콘솔에서 종료하여 복구할 수 있습니다( killall vim다른 콘솔이 있고 vim이를 유지하려는 경우는 제외).

이것이 당신이 관찰하는 광기입니다. 범인은 또는 의 범위 를 벗어났습니다 stty sane.resettput reset


하찮은 일

  1. 다음 명령은 다른 광기를 생성합니다.

     <<<"foo" tee >(vim -)
     <<<"foo" tee > >(vim -)
    

첫 번째 경우는 >()메인 쉘에 의해 처리되고 vim쉘의 프로세스 그룹에 배치됩니다. 일단 종료되면 터미널에서 데이터를 읽을 수 있습니다 tee(비록 쉘이 간섭하기는 하지만) strace.

두 번째 경우는 >()처리 쉘에 의해 처리됩니다 >. (exec to)가 되는 서브쉘입니다 tee. 실제로 vim는 프로세스 그룹에 배치됩니다 tee. 포그라운드에 있는 한 tee터미널에서 데이터를 읽을 수 있습니다.

거의 즉시 종료되기 때문에 tee첫 번째 항목은 vim터미널에서 거의 즉시 읽을 수 있지만 두 번째 항목은 vim거의 즉시 읽을 수 없습니다.

  1. 내 테스트에 따르면 >(vim -)Zsh는 처리가 아닌 다른 프로세스 그룹에 있으며 절대 vim포 그라운드에 있을 수 없는 것으로 나타났습니다. 다른 차이점이 있는 것 같지만 자세한 내용은 다루지 않겠습니다.>()vim

일반 솔루션(에 의존하지 않음 strace)

  • 작업 제어가 비활성화되면( set +m서브셸에서 코드를 사용하거나 실행하여) 모든 새 프로세스는 터미널이 전경으로 처리하는 그룹에 속하게 됩니다. 쉘로의 복귀를 지연하면 쉘은 터미널에서 데이터를 읽는 것을 방해하지 않습니다. 이 시도:

      (strace -o >(vim -) file.out; sleep 99999)
    

종료 후 Ctrl+ 종료를 사용하십시오 C. 이 조합을 클릭하시면 단말기도 동일하게 구성되어 있으므로 영향을 받지 않습니다.sleepvimvimsleepvimstty -isig

이 솔루션은 그다지 우아하지 않습니다. 작업 제어를 비활성화하고 쉘이 입력을 읽지 못하게 하는 것이 어떻게 영향을 미치는지 보여주기 때문에 이것을 여기에 넣었습니다.

  • 또는 vim전경에서 시작하고 유지해야 합니다. 사용하지 마세요 >(vim -). vim …또는 를 사용하세요 … | vim -.

가장 간단한 방법은 일반 파일을 만들고(귀하의 경우 strace -o somefile file.out) 나중에 여는 것입니다( vim somefile).


솔루션은 구체적으로 대상을 지정합니다.strace

파일 생성을 피하고 사용하거나 가능한 vim <(strace …)솔루션 입니다. 나는 당신이 충분히 똑똑하다면(그리고 당신이 가지고 있습니까?) 원본 stdout과 병합하지 않고도 파일 설명자를 조작하고 stdout으로 파이프할 수 있다고 strace … | vim -생각합니다 ./proc-o

옳은 일그러나 strace제공된 다음을 사용하십시오 -o.

-o filename
--output=filename

filenamestderr 대신 파일에 추적 출력을 씁니다 . […]인수가 |또는 로 시작하는 경우 !인수의 나머지 부분은 명령으로 처리되고 모든 출력이 해당 명령으로 파이프됩니다.이를 통해 실행된 프로그램의 리디렉션에 영향을 주지 않고 디버그 출력을 프로그램으로 쉽게 파이프할 수 있습니다. […]

(원천, 강조 내)

귀하의 명령은 다음과 같습니다

strace -o '|vim -' file.out

인용 하거나 |이스케이프해야 합니다. 그렇지 않으면 쉘이 파이프를 구축하려고 시도합니다. 또 다른 옵션은 !일부 쉘에서입니다.보호받아야 한다게다가.

strace달려 sh.shvim​위의 문제가 해결되었습니다. 각기:

  1. 이 세 프로세스는 동일한 프로세스 그룹에 속합니다. strace프런트에 있으면 프런트에 있습니다 vim.

  2. 대화형(외부) 쉘은 종료 후에만 터미널에서 읽기를 시도합니다 strace.shvim

관련 정보