zsh가 *17*과 같은 파일 글로브를 좋아하지 않는 이유는 무엇입니까?

zsh가 *17*과 같은 파일 글로브를 좋아하지 않는 이유는 무엇입니까?

저는 비교적 새로운 zsh 사용자이고 99%의 시간 동안 그것을 좋아합니다. 예를 들어 여러 파일을 복사하려고 하면 다음과 같습니다.

[I] ➜ ls *17*
core.txt.17   info.17       vmcore.17.zst

하지만 그렇게 하면 다음과 같은 scp *17* xxx:xxx/xxx결과를 얻습니다.

[I] ➜ scp *17* freefall.freebsd.org:
*17*: No such file or directory

ler in /var/crash  at borg
[I] ➜

왜?

을 실행하면 type scp다음을 얻습니다.

scp is an alias for noglob scp
scp is /usr/bin/scp

답변1

아시다시피 zsh에는 특정 명령에 대해 와일드카드 확장을 비활성화하는 방법이 있습니다. 당신이 넣으면noglobzsh는 명령 앞의 명령 단어를 와일드카드로 확장하지 않습니다. 입력은 noglob종종 인수에 와일드카드를 인용하는 것만큼 힘들기 때문에 가장 일반적인 용도는 명령 이름을 접두사를 사용하여 동일한 명령 이름의 별칭으로 만들어 특정 명령을 자동으로 "일치하지 않게" 하는 것입니다 noglob. 예를 들어,

alias scp='noglob scp'

명령줄에서는 와일드카드 확장을 사용할 수 없지만 scp그 외에는 scp명령이 정상적으로 실행됩니다.

별칭을 우회할 수 있습니다.

\scp *17* freefall.freebsd.org: 

또는

=scp *17* freefall.freebsd.org: 

\scp별칭을 무시하고 해당 이름으로 함수, 내장 또는 외부 명령을 찾습니다. =scp외부 명령만 찾습니다.

scp매개변수를 방지하는 와일드카드 확장을 사용하면 따옴표 없이 쓸 수 있지만 scp remote:*17*, 가장 큰 단점은 쓸 수 없다는 것입니다 scp *17* remote:. 한 단계 더 나아가 scp매개변수가 원격 파일 이름과 같지 않은 경우에만 와일드카드를 확장할 수 있습니다. 이는 인수를 구문 분석 scp하고 옵션이나 원격 파일 이름처럼 보이지 않는 인수의 와일드카드 문자만 확장하는 함수입니다 .

function glob_non_remote {
  local a x
  a=($1); shift
  for x; do
    # Do wildcard expansion manually, but only for arguments that don't look
    # like options or remote file names.
    case $x in
      (*:*|-*|) a+=("$x");;
      *) a+=($~x);;
    esac
  done
  "${(@)a}"
}
alias scp='noglob glob_non_remote scp'

관련 정보