zsh가 이러한 기능에서 하이픈을 밑줄로 바꾸는 이유는 무엇입니까?

zsh가 이러한 기능에서 하이픈을 밑줄로 바꾸는 이유는 무엇입니까?

zsh 및 bash 콘솔에서 다음 함수 별칭을 얻습니다.

compose() {
  docker-compose $*
}

run() {
  compose "run --rm app $*"
}

rails() {
  run "rails $*"
}

Bash에서 rails cdocker-compose를 통해 실행하면 Ruby on Rails 콘솔이 성공적으로 시작되었습니다.

zsh에서 실행하면 rails c명령을 찾을 수 없음 오류가 발생하고 하이픈이 밑줄로 대체됩니다.

➜ rails c
No such command: run __rm app rails c

내 zsh 버전:

➜ zsh --version
zsh 5.6.2 (x86_64-apple-darwin18.0.0)

답변1

zsh대시를 밑줄로 바꾸는 것은 아니지만 해당 docker-compose프로그램일 수도 있고 호출하는 다른 프로그램일 수도 있습니다.

문제는 따옴표가 없는 변수 zsh와 달리 bash기본적으로 분할되지 않는다는 것입니다 IFS.

docker-compose함수로 정의 하고 각 인수를 동봉하여 인쇄하면 {}다음과 같은 결과를 얻습니다.

$ cat example
docker-compose() {
        echo -n docker-compose
        for f in "$@"; do echo -n " {$f}"; done; echo
}
compose() { docker-compose $*; }
run() { compose "run --rm app $*"; }
rails() { run "rails $*"; }   
rails c

$ zsh example
docker-compose {run --rm app rails c}

$ bash example
docker-compose {run} {--rm} {app} {rails} {c}

run--rm, , 등이 app에서는 별도의 인수로 전달되고 bash에서는 단일 인수로 전달되는 방식에 유의하세요 zsh.

이는 변수가 실제로 공백( 의 기본값)을 구분 기호로 사용하여 bash여러 인수로 분할되고 잘리기 때문입니다. 대신 또는 옵션을 사용하여 동일한 효과를 얻을 수 있지만 이렇게 하면 스크립트가 zsh만 지원하게 됩니다.$*IFSzsh$=*$*set -o SH_WORD_SPLIT

다음과 같은 특별한 이유가 없는 한 모든 곳에서 사용하기 "$@"보다는 사용해야 합니다 .$*

compose() { docker-compose "$@"; }
run() { compose run --rm app "$@"; }
rails() { run rails "$@"; }

관련 정보