zsh 완성 기능에서 작은따옴표가 포함된 파일 이름을 처리하는 방법은 무엇입니까?

zsh 완성 기능에서 작은따옴표가 포함된 파일 이름을 처리하는 방법은 무엇입니까?

나는 zsh쉘을 사용하고 있으며 내 코드에는 다음이 있습니다 .zshrc.

fpath=(~/.zsh/completion $fpath)
autoload -Uz _vc

autoload -Uz compinit
compinit

첫 번째 줄은 ~/.zsh/completion환경 변수에 저장된 배열에 경로를 추가합니다 fpath.

두 번째 _vc줄은 이름이 지정된 사용자 정의 셸 함수에 대해 이름이 지정된 완성 함수를 로드합니다 vc. vc특정 폴더( ) ~/.cheat내의 파일을 편집하는 용도로만 사용 됩니다. _vc파일에 정의되어 있습니다 ~/.zsh/completion/_vc.

마지막 두 줄은 완성 시스템을 활성화합니다.

완성된 함수에 대한 코드는 다음과 같습니다 _vc.

#compdef vc

declare -a cheatsheets
cheatsheets="$(ls ~/.cheat)"
_arguments "1:cheatsheets:(${cheatsheets})" && return 0

이것부터 복사했어요주소, 내 필요에 맞게 조정했습니다.

디렉터리에 이름에 작은따옴표가 포함된 파일이 없으면 ~/.cheat완성이 작동합니다 . 그러나 예를 들어 하나라도 있는 경우 foo'bar다음 오류 메시지와 함께 완료가 실패합니다.

(eval):56: unmatched '
(eval):56: unmatched '
(eval):56: unmatched '
(eval):56: unmatched '

줄의 큰따옴표를 cheatsheets="$(ls ~/.cheat)"작은따옴표로 바꾸는 솔루션을 찾았습니다 cheatsheets='$(ls ~/.cheat)'.

이제 명령 Tab다음에 클릭 하면 zsh가 include vc내의 파일을 제안합니다 (zsh가 자동으로 작은따옴표를 이스케이프 처리한 것 같습니다).~/.cheatfoo\'bar

그러나 나는 그것이 어떻게, 왜 작동하는지 이해하지 못합니다. 작은따옴표를 사용하는 경우 변수에는 cheatsheets리터럴 문자열이 포함되어야 합니다. 따라서 $(...)명령 대체를 확장해서는 안 됩니다. 예를 들어, 다음 명령을 실행하면:

myvar='$(ls)'
echo $myvar    →    outputs `$(ls)` literally

그렇다면 왜 '$(ls ~/.cheat)'확장해야 할까요 _arguments "1:cheatsheets:(${cheatsheets})" && return 0? 내부의 작은따옴표를 자동으로 이스케이프 처리하는 이유는 무엇입니까 foo'bar?

답변1

우리가 일을 잘못된 방식으로 고집한다면™

#compdef vc

declare -a cheatsheets
cheatsheets=(${(f)"$(ls ~/.cheat/)"})
_arguments '1:cheatsheets:(${cheatsheets})' && return 0

이런! 물론 파일 이름에 개행 문자가 포함되어 있으면 분할되므로 중단됩니다 (f).어쨌든 구문 분석 ls은 나쁜 생각입니다.; ZSH는 glob 파일을 배열에 직접 넣을 수 있습니다.

% mkdir ~/.lojban
% touch ~/.lojban/{go\'i,na\ go\'i}
% words=(~/.lojban/*) 
% print -l ${words:t}
go'i
na go'i
% words=(~/.lojban/*(On))
% print -l ${words:t}    
na go'i
go'i
% 

하지만 아마도 로컬 배열은 필요하지 않을 것입니다. _filesglob에서 수행할 수 있습니다.

#compdef vc
_arguments '1:cheatsheets:_files -g "~/.cheat/*"' && return 0

검색 디렉터리에 사용할 수 있는 기본 파일 이름만 원하는 경우 정규화된 파일 경로가 반환됩니다.

#compdef vc
_arguments '1:cheatsheets:_files -W ~/.cheat' && return 0

관련 정보