다음과 같은 간단한 명령이 있습니다.
$ echo <(vipe)
편집할 수 있는 vim 버퍼를 열고 작업이 끝나면 vim 버퍼의 내용을 보관하기 위해 할당된 임시 파일의 이름을 에코합니다.
대신, vim 버퍼는 특정 키 입력에 응답하지 않고 매우 이상하게 동작하며 결국 vim이 완전히 충돌합니다.
내 가정 중 어느 것이 잘못되었나요?
답변1
먼저 터미널에 표시되는 내용을 살펴보겠습니다.
$ echo <(vim)
/dev/fd/63
$ Vim: Warning: Output is not to a terminal
편집기가 종료될 때까지 기다리지 않고 즉시 프롬프트를 받게 됩니다. 프로세스 교체는 명령이 완료될 때까지 기다리지 않고 명령과 셸 사이에 파이프를 만듭니다. 파이프의 이름은 process가 인수로 대체하는 명령에 전달됩니다. 여기서 echo
이름은 즉시 인쇄되어 반환되며, 그 후 bash는 파이프를 닫습니다.
표준 입력과 표준 오류가 터미널에 연결되어 있는 Vim은 여전히 실행 중이지만, 표준 출력은 연결되어 있지 않습니다. 따라서 Vim은 입력을 받고 일부 오류 메시지를 표시하지만 대부분의 표시는 깨진 파이프인 표준 출력으로 진행됩니다.
bash와 vim 모두 터미널에서 읽습니다. 이로 인해 키 입력이 어느 쪽이든 무작위로 전송됩니다. 이런 일은 일반적으로 발생하지 않습니다.백스테이지 과정예터미널에서 읽기 비활성화— 이 작업을 시도하면 SIGTTIN 신호를 받게 되며, 신호를 무시하면 호출에서 read
오류가 반환됩니다. 그러나 이 경우 vim
포그라운드 프로세스 그룹의 일부로 실행하면 프로세스 교체가 새 프로세스 그룹을 생성하지 않으므로 터미널에서 읽고 일부 키 입력을 캡처할 수 있습니다.
어느 시점에서 Vim은 더 이상 참을 수 없다고 판단하고 종료합니다. 무엇이 그런 결정을 하게 되었는지 모르겠습니다.
프로세스 교체는 임시 파일을 생성하지 않고 파이프를 생성하므로 접근 방식이 의미가 없습니다.지쉬임시 파일( )을 생성하는 프로세스 교체 구조가 있지만 =(somecommand)
그것도 작동하지 않습니다. 를 실행하면 echo =(vipe </dev/null)
인쇄 시 방금 삭제된 임시 파일의 이름이 인쇄됩니다.
원하는 작업을 수행하려면 임시 파일 삭제를 직접 처리해야 합니다. 나는 당신을 도울 수 있는 쉘 구조가 없다고 생각합니다. mktemp
임시 파일을 생성한 다음 일반적인 방법으로 편집하려면 호출하세요 .
tmpfile=$(mktemp)
"${VISUAL:-"${EDITOR:-vi}"}" "$tmpfile"
echo "$tmpfile"
…
rm "$tmpfile"