xargs로 Vim을 호출 한 후 터미널이 중단됨


30

때로는 xargs다음과 같이을 사용하여 Vim을 호출하려고 시도 했습니다.

find . -name '*.java' | xargs vim

… 어떤 종류의 작품 :

  1. Vim이 시작되면 다음 경고가 잠깐 동안 깜박입니다.

    Vim: Warning: Input is not from a terminal
    
  2. 편집 작업 — :files모든 .java파일을 예상대로 올바르게 열거합니다 .
  3. 저장하고 종료 할 수 있습니다.

그러나 Vim을 종료 한 후 터미널이 멈췄습니다.

  • 쉘 프롬프트에서 입력 한 내용은 에코되지 않습니다.
  • 캐리지 리턴은 전혀 표시되지 않으며 줄 바꿈 만 표시됩니다.

reset(1)터미널을 다시 초기화하라는 명령을 내릴 때까지 계속됩니다 .

이것은 Vim 버그입니까, 아니면 왜 그런 터미널과 상호 작용하는지에 대한 더 만족스러운 설명이 있습니까? 나는 Linux와 다양한 Unices에서 Vim에서 버전 7.3 (버전은 중요하지 않은 것)까지 발생하는 것을 보았습니다.

하나의 해결 방법, 즉을 알고 vim $(find . -name '*.java')있습니다. 다른 해결 방법은 환영받을 것입니다.하지만 이것이 내 주요 질문은 아닙니다.


가능한 많은 질문으로이 사이트를 채우고 자하는 여러분의 소망을 얻었지만… 그 질문은 SO / SU와 다른 곳에서 수십 년에 걸쳐 수십 번 대답되었습니다 : Vim이 사용할 수없는 xargs더미 stdin를 사용하고 그 후의 모든 것.
romainl

1
@romainl 나는 그 사이트에서 활동적이지 않으며, 정직한 질문을 본 적이 없다.
200_success

관련 : superuser.com/questions/336016/…- 아마도 누군가가 최고의 답변을 훌륭한 답변으로 요약 할 수 있습니다.
muru

2
좋은 질문-이것은 나에게 여러 번 일어났다. 또한 다른 SO 사이트를 사용하지 않습니다. vim과 관련된 경우 여기에서 찾고 싶습니다.
craigp

답변:


21

이는 vim이 호출되고 터미널 대신 이전 파이프 라인의 출력에 연결되어 있고 예상치 못한 다른 입력 (NUL과 같은)을 수신 할 때 발생합니다. 당신이 실행할 때와 동일한 상황이 발생합니다 vim < /dev/null, 그래서 reset이 경우 명령을 할 수 있습니다. 이것은 수퍼 유저의 grawity에 의해 잘 설명되어 있습니다 .

find편집 할 파일 이름을 전달 하는 데 사용 하는 경우을 xargs사용할 필요가 없습니다 -exec. 예를 들면 다음과 같습니다.

find . -name '*.java' -exec vim {} +

을 사용하려면 xargsUnix / macOS에서 다음 -o과 같은 매개 변수 를 사용해야합니다 .

find . -name '*.java' | xargs -o vim

-o명령을 실행하기 전에 하위 프로세스에서 stdin을 / dev / tty로 다시여십시오. 이는 xargs가 대화식 응용 프로그램을 실행하도록하려는 경우에 유용합니다.

또는:

find . -name "*.java" -type f -print0 | xargs -o -0 vim

참고 : -print0/ -0를 사용하면 공백이있는 파일 이름이 지원됩니다.


find+ BSDxargs

Unix / macOS에서는 다음 해결 방법을 시도 할 수 있습니다.

find . -name '*.java' | xargs -J% sh -c 'vim < /dev/tty $@'

다음과 같은 명령 대체 구문을 사용할 수도 있습니다 .

vim $(find . -name '*.java')
vim `find . -name '*.java`

또는 다음과 같이 tty 할당을 강제 parallel로 수행 xargs하는 대신 GNU 를 사용하십시오 .

find . -name '*.java' | parallel -X --tty vi

참고 : parallelUnix / OSX에서는 매개 변수가 다르고 tty를 지원하지 않으므로 작동하지 않습니다.

잘 (등 다른 많은 인기 명령은 의사 청각 장애 할당을 제공 -t에서 ssh), 그래서 도움이 있는지 확인합니다.

다른 제안은 다음을 사용하는 것입니다.

관련 :


내 GNU xargs에는이 없습니다 -J. GNU 버전에는없는 MacOS (BSD) 옵션 인 것 같습니다.
추후 공지가있을 때까지 일시 중지되었습니다.

12

해결 방법 제안 : 파일 시스템 탐색기로 버퍼 사용

vim -stdin에서 경로 목록을 읽으려면 이 명령을 사용하십시오 . Vim의 :help --설명 : 1

stdin에서 읽은 텍스트로 채워진 새 버퍼 편집을 시작하십시오. 일반적으로 stdin에서 읽는 명령은 이제 stderr에서 읽습니다. 예:

find . -name "*.c" -print | vim -

그런 다음 사용 gf하거나 Ctrl-wCtrl-f같은 버퍼 또는 각각 새로운 분할 창에서 파일로 이동합니다.

해결 방법 제안 : 인수 목록

또 다른 좋은 방법은 Vim의 인수 목록을 사용하는 것입니다. 이 :argadd **/*.java명령은 Vim의 인수 목록을 현재 디렉토리 내에서 발견 된 모든 java 파일로 재귀 적으로 채 웁니다. 그런 다음 사용할 수 있습니다 :next:prev파일 사이를 이동합니다.


1 첫 번째 -는 Vim에게 명령 행 옵션에 대한 도움말을 검색하라고 말하고, 두 번째는 실제로 검색중인 명령 행 플래그입니다. :help help-context이와 같은 더 많은 트릭을 읽으십시오 .


8

게다가 reset, 당신은 시도 할 수 있습니다 :

stty sane

터미널을 다시 사용할 수있게해야합니다.

설명 은 여기 를 참조 하십시오 . 그리고 어떻게 든 이것이 vim 오작동으로 간주 될 수 있습니다. 적어도 Neovim 에는이 문제가 없습니다.


이것은 정확히 질문에 대한 대답은 아니지만 도움이되었으므로 +1입니다.
복원 Monica Monica iamnotmaynard

이것은 내 질문에 대답합니다.) OP를 읽은 후에도 더 reset해야한다고 생각 합니다.
Sridhar Sarnobat

1

그 이유는 인 xargs세트 stdin하는 /dev/null반면 vim요구 stdin/dev/tty.


BSD xargs(예 : Mac) 솔루션 :

echo -e 'file1\nfile2' | xargs -o vim

-o설정합니다 stdinxarg의 자식 프로세스 ( vim이 경우)에 dev/tty.


GNU xargs(예 : Linux) 솔루션 :

GNU xargs에는 -o옵션 이 없습니다 . 대신 더 복잡한 해결 방법을 사용해야합니다. (참고 : 후행 zero문자열 을 갖는 것이 매우 중요 합니다. 잊지 마십시오.)

echo -e 'file1\nfile2' | xargs bash -c '</dev/tty vim "$@"' zero

별명으로 만들 수도 있습니다.

alias vimin='xargs bash -c '\''</dev/tty vim "$@"'\'' zero'
echo -e 'file1\nfile2' | vimin

GNU xargs 솔루션에 대한 자세한 설명

단계별로 분류 해 보겠습니다.

echo -e 'file1\nfile2' | xargs bash -c '</dev/tty vim "$@"' zero

1. xargs단순히 stdin문자열 끝에를 추가 하므로 xargs다음을 실행합니다.

    bash -c '</dev/tty vim "$@"' zero file1 file2

의 형식은 bash -c입니다 bash -c 'COMMAND_STRING' $0 $1 $2 etc.

"$@"위치 매개 변수 "$1", "$2"등으로 확장됩니다. "$ 0"은 포함되지 않습니다. 이는 위치 매개 변수 가 아닌 스크립트 이름에 대한 특수 매개 변수이기 때문입니다. 따라서 우리는 대신에 더미 문자열 zero(모든 문자열이 될 수 있음)을 추가해야합니다 $0. 그렇지 않으면 첫 번째 파일이 손실됩니다.

따라서 확장 "$@"하면 다음과 같이 끝납니다.

    bash -c '</dev/tty vim file1 file2' 

3. bash -cCOMMAND_STRING을 실행합니다 :

    </dev/tty vim file1 file2 

</dev/tty는 설정 stdin/dev/tty그 있도록 vim대화 형 모드에서 작업 할 수 있습니다.


+1 이것은 가장 많은 표를 얻은 답변과 중복 된 것으로 보이지만 그렇지 않습니다. $0(여기서 "제로") 자리가 핵심이다.
추후 공지가있을 때까지 일시 중지되었습니다.

0

나는이 모든 대답이 부족하다는 것을 알았습니다. xargs 문제를 해결하기 위해 노력한 후 일반 상자에서 이러한 검색 및 열기를 수행하는 가장 간단한 방법은 다음과 같습니다.

vim -O `grep -lir mySearchTerm *`

내가 사용에는 문제가 없습니다 findxargs하고 grep,하지만 난 구문이 성가신 찾을 수 있습니다. 그리고 vim터미널을 IDE로 사용 하고 파일에서 속성을 지속적으로 검색 하는 매일의 코더 로서 이것이 내가 사용하고있는 것입니다.

find . -path ./node_modules -prune -o -name '*.js' | xargs grep -i mySearchTermvim을 통한 파일 열기 및 기타 방법과 함께 시간과 장소가 있습니다. 나를 위해, 그것은 거의 없습니다.

이것이 누군가를 돕기를 바랍니다.


2
그러나 레거시 백틱 표기법을 사용 $(...)하지 말고 대신 사용하는 것이 좋습니다. 그것은 스크립트로 명령 줄에서 중요하지 않다하지만 난 그것을 사용하는 것이 여전히 더 나은 생각 답 : (참조에 여기여기 )
statox
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.