![TAB 키를 누를 때까지 zsh 경로 완성 마법이 발생하지 않도록 하려면 어떻게 해야 합니까?](https://linux55.com/image/209877/TAB%20%ED%82%A4%EB%A5%BC%20%EB%88%84%EB%A5%BC%20%EB%95%8C%EA%B9%8C%EC%A7%80%20zsh%20%EA%B2%BD%EB%A1%9C%20%EC%99%84%EC%84%B1%20%EB%A7%88%EB%B2%95%EC%9D%B4%20%EB%B0%9C%EC%83%9D%ED%95%98%EC%A7%80%20%EC%95%8A%EB%8F%84%EB%A1%9D%20%ED%95%98%EB%A0%A4%EB%A9%B4%20%EC%96%B4%EB%96%BB%EA%B2%8C%20%ED%95%B4%EC%95%BC%20%ED%95%A9%EB%8B%88%EA%B9%8C%3F.png)
저는 여러 개의 USB 하드 드라이브가 포함된 취미용 서버를 가지고 있습니다. 이러한 드라이브는 필요할 때 빠르게 액세스할 수 있는 본질적으로 콜드 스토리지이기 때문에 공격적인 전원 관리와 짧은 스핀업 시간 초과를 활성화했습니다. 따라서 대부분은 액세스해야 할 때까지 APM 대기 시간의 99.9%를 소비하며, 전원이 켜지면 단일 드라이브의 경우 10초 이내에 액세스할 수 있고 RAID 드라이브의 경우 최대 30초에 액세스할 수 있습니다. .
ZSH 완성 시스템은 이와 관련하여 나에게 두통을 안겨줍니다. 왜냐하면 그것이 제공하는 자동 완성 기능은 꽤 멋진데, TAB을 누르지 않아도, 쉘 명령을 탐색하기 위해 화살표를 사용하더라도 일종의 자동 경로 유효성 검사도 수행하기 때문입니다. 히스토리 키.
예를 들어 를 입력한 rsync
다음 위쪽 키를 눌러 rsync
이전 명령의 기록을 살펴보기 시작한 다음 마법이 완료되면 즉시 해당 명령 내의 파일 시스템 경로에 액세스하여 마법 작업을 확인하고 수행합니다. 이로 인해 zsh가 차단되고 응답하지 않는 대규모 일시 중지가 발생할 뿐만 아니라 최대 절전 모드 드라이브를 회전시켜 해당 스피너의 마모를 증가시킵니다. 모든 네트워크 설치 경로는 네트워크 특성으로 인해 지연이 발생할 수도 있습니다.
경로를 작성할 때도 작동합니다. 문자, 슬래시, 와일드카드만 입력하면 됩니다.
비슷한 불만이 많이 보이던데,이와 같이, 하지만 이 문제를 정확히 해결하는 방법을 찾지 못했습니다.
위에서 언급한 게시물에는 zsh Completion System 문서에 대한 링크가 있으며, 이를 읽는 동안 여전히 혼란스러워졌습니다. 문서를 보면 구문이 무엇인지도 잘 모르겠고 zstyle
많은 용어 때문에 혼란스럽습니다.
기본적으로 저는 zsh에게 다음과 같이 말할 방법을 찾고 있습니다. "들어봐, 난 당신이 하는 일이 마음에 들지만, 당신의 모든 마법을 사용하고 내가 TAB 키를 누를 때까지 기다려 주실 수 있나요?"
답변1
Zsh는 "일반" 구성에서 Tab 키를 누르지 않는 한 어떤 종류의 완료 마법도 수행하지 않습니다. 가능하지만 몇 가지 심각한 확장이 필요합니다.
zsh 구성 프레임워크를 사용하는 경우 아마도 이 기능이 표준으로 제공될 것입니다. 비활성화하는 방법을 찾으려면 zsh 자체에 대한 문서가 아니라 해당 프레임워크에 대한 문서를 찾아야 합니다.
이 기능에 대한 설명을 토대로라인 편집기어떤 방식으로든 사용자 정의되었을 것입니다. 이 동작을 수행하기 위해 어딘가에 후크를 정의할 수 있는지 아니면 자체 삽입을 재정의해야 하는지 잘 모르겠습니다. 주요 입찰 목록을 작성 bindkey
하고 눈에 띄는 것이 있는지 확인하십시오. 어쩌면 당신이 얻는 것과 비교할 수도 있습니다 (이것은 다른 구성 파일을 zsh -f
읽지 않고 zsh를 시작합니다 )..zshrc
무슨 일이 일어나고 있는지 혼란스럽다면 실행되는 모든 명령을 파일에 기록하도록 지시할 수 있습니다. ( set -x
단말기에 간단한 로그가 있지만 실제로 사용하기에는 너무 많을 것 같습니다.)
exec 2>zsh.log; set -x
취소:
set +x; exec 2>/dev/tty
완료 프로세스를 추적하려면(완료되지 않은 장면에서 완료와 같은 작업을 트리거하는 대신) 다음 명령을 실행할 수 있습니다._complete_debug
( ^X?
기본적으로 바인딩됨)을 누르는 대신 Tab.
zsh 문서는 읽기 어렵습니다. 수행하려는 작업에 가까운 예제를 찾은 다음 필요할 수 있는 명령/변수/함수/...를 찾은 후 문서를 살펴보는 것이 좋습니다. 이것zstyle
문서에서는 작동 방식을 설명하지만 완성 시스템에서 사용되는 방식을 이해하려면 이해해야 합니다.사용된 zstyle 컨텍스트의 완성 구문, 그것이 어디에 사용되는지 알기 위해서는 그것을 사용하는 함수에 대한 문서를 찾거나 때로는 소스 코드를 읽어야 합니다. 어쨌든, 문제를 해결하기 위해 zstyle에 대해 아무것도 알 필요가 없습니다. 완료 구성만으로는 완료 외부의 자동 동작을 트리거할 수 없습니다(아마도 자동 동작이 완료를 모방하고 해당 설정을 재사용할 수 있지만 전혀 아닐 수도 있습니다). 줄 편집기는 약간, 아마도 여러 가지 사용자 정의 키 바인딩을 구성해야 합니다.
답변2
(경고: 이야기 시간을 좋아하고 내가 어떻게 디버깅하고 범인을 찾았는지에 관심이 있는 경우에만 이 내용을 읽으십시오. 어떤 사람들은 긴 내용을 잘 처리하지 못합니다. 만약 당신이 그런 사람이라면 이것은 당신을 위한 것이 아닙니다.)
좋아, 범인을 알아낸 방법을 문서화할 것이기 때문에 원래 질문을 업데이트하는 대신 이것을 "답변"으로 추가합니다. 실제 질문("누가 내 (오 이런) zsh를 지연시키는 원인인지"에 대한 실제 대답은 위의 Giles의 답변입니다. 이것은 그의 팁에 대한 부록일 뿐입니다. "오 이런 ZSH"를 디버깅하는 다른 사람들에게 유용할 것이라고 생각했습니다. ). "당신이 좋아하는 것을 거기에 넣으세요(이것을 싫어하지 마세요).
다음은 구성에 대한 변경 사항을 테스트하는 데 사용된 몇 가지 특정 문제입니다.
- 예를 들어 회전이 중지된 드라이브에 있는 폴더 경로에 열린 세션이 있습니다
/media/drive-f/Apps
. 드라이브가 회전을 중지할 만큼 오랫동안 이 세션을 종료했지만 zsh 세션은 여전히 해당 경로에 있습니다. 홈 폴더로 돌아가고 싶어서 을cd
클릭하자마자c
zsh가 차단되고 드라이브가 회전합니다. 내가 키보드를 치는 것에 대한 반응으로 현재 디렉토리를 확인하려는 것이 있습니다. - 회전하는 드라이브의 위치에 경로를 입력하거나 전체 경로를 붙여 넣을 때 zsh 환경에서 실행 중인 무언가가 Enter 또는 Tab을 누르기 전에 드라이브를 확인하려고 하며 드라이브가 회전하는 동안 차단됩니다. 예를 들어
/media/drive-k/Apps
경로를 붙여넣으면 쉘이 차단됩니다. 입력하면A
"응용 프로그램"에 입력하면 쉘이 차단됩니다.
따라서 Giles의 답변에 대해 언급했듯이 첫 번째 테스트는 그의 트릭을 사용 zsh -f
하고 전체 일반 zsh 세션을 얻는 것입니다. 예를 들어 TAB을 누르거나 ls
위치를 회전하지 않는 한 전혀 문제가 없습니다 . 위치가 어딘가에 캐시되어 있는 한 드라이브를 회전시키지 않고도 TAB을 사용하여 회전 중지 위치로 이동할 수도 있습니다. 예를 들어 Tab 키를 사용 /media/drive-d/Projects
하여 전환 /media/drive-d/P<TAB>
하고 d 드라이브가 여전히 회전할 수 있습니다. 이 작업을 수행할 때만 ls -l
드라이브가 회전합니다.
좋아요 다음 단계는 Gilles의 로깅 기술을 시도하는 것입니다. 이 로깅은 매우 장황하며 플러그인을 활성화하면 z
당시 내가 있던 위치와 전혀 관련이 없는 디렉터리에 대한 혼란스러운 로그를 많이 얻었습니다. 또한 셸을 차단하는 경로로 이동할 때 로그는 블록이 해제될 때까지 침묵을 유지하며, 이 시점에서 로그는 많은 출력을 렌더링하므로 차단이 단일 "외부 작업"의 일부인 것처럼 보입니다(아마도 이는 최선의 표현은 아닙니다. 또한 모든 디버깅 출력 모음을 캡슐화합니다. 나는 블록의 범인이 실행되기 시작할 때까지 일련의 줄을 로그에 표시한 다음 일시 중지하고 더 많은 줄을 표시하고 싶었습니다.
이는 사실이 아니었고 위의 두 가지 문제를 재현하려고 시도하면서 모든 플러그인을 비활성화하고 하나씩 다시 활성화하기로 결정했습니다. 모든 드라이브의 회전 시간 제한을 30초로 설정했습니다. sudo hdparm -S 6 /dev/disk/by-id/usb-*0:0
(USB 버스의 모든 드라이브를 대상 으로 하며 ( 초는 num의 배수) 5, 즉 30초를 사용하여 해당 드라이브의 파티션을 대상으로 삼는 0:0
것을 피하기 위해 접미사를 사용합니다.) .hdparm
-S <num>
여기서 절차는 ~/.zshrc
모든 플러그인(내가 가지고 있는 plugins=(colored-man-pages git-extras history pj redis-cli urltools z zsh-syntax-highlighting)
)을 편집하고 비활성화하는 것입니다. 그런 다음 두 개의 새로운 SHELL(업데이트된 구성을 읽기 위해)에서 두 번째 문제를 재현할 수 있도록 하나를 탐색 하고 첫 번째 문제를 재현할 준비가 되도록 /media/drive-b/Projects
빈 셸로 이동합니다 . /home/daniel
그런 다음 30초 동안 기다렸다가 이 작업을 수행해 보세요.
플러그인이 로드되지 않으면 쉘이 두 문제를 재현하지 않는다는 것을 확인할 수 있습니다.
그런 다음 범인을 찾을 때까지 각 플러그인을 순서대로 다시 활성화한 다음 설명된 대로 새 zsh 세션을 열고 30초 이상 기다렸습니다(즉시 URL ~ 경로 때문에 urltools가 범인이라고 생각하는 동안)(전체 면책조항, 디버깅하는 동안 과거형으로 작성되어 아직 잘 모르겠습니다. 맞는지 확인해 보겠습니다 [서스펜스 음악])).
내가 틀렸어. 나는 끝까지 계속해서 모든 플러그인을 다시 활성화했습니다 zsh-syntax-highlighting
. 그런데 문제가 다시 시작되었습니다. 나는 즉시 뭔가 빠졌거나 뭔가 잘못 테스트하고 있다고 생각했습니다(아마도 변경 사항을 읽기 위해 새 셸을 여는 것을 잊었나요?). 그래서 이를 제거 zsh-syntax-highlighting
하고 문제를 더 광범위하게 재현하려고 노력했습니다. 괜찮아요. 모든 것이 평소대로 진행됩니다.
실제로 이것은 의미가 있습니다. cd
명령이 실행되면 녹색으로 변하는 플러그인 입니다 . 해당 디렉토리 에 있을 때 cdroms
회색으로 인쇄하려고 합니다 . 나는 이 기능을 좋아한다. 그러나 이러한 단점을 견딜 수 있을 만큼 충분하지는 않습니다. XD.
아, 서버가 복구되어서 다행이네요. 도와줘서 고마워요, 자일스. 다른 사람들도 이것을 사용할 수 있기를 바랍니다.