Por que o zsh substitui os hifens por sublinhados nessas funções?

0

Eu tenho os seguintes aliases de função originados em consoles zsh e bash:

compose() {
  docker-compose $*
}

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

rails() {
  run "rails $*"
}

No bash, executar rails c inicia um console Ruby on Rails por meio do docker-compose com êxito.

No zsh, a execução de rails c resulta em um erro de comando não encontrado, em que os hífens são substituídos por sublinhados:

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

Minha versão do zsh:

➜ zsh --version
zsh 5.6.2 (x86_64-apple-darwin18.0.0)
    
por Nathan 22.10.2018 / 18:13

1 resposta

5

Não é zsh que está substituindo traços por sublinhados, mas provavelmente esse programa docker-compose ou outro programa chamado por ele.

O problema é que zsh , ao contrário de bash , não divide variáveis não citadas com IFS por padrão.

Se eu definir docker-compose como uma função que imprime cada um dos seus argumentos entre {} , é isso que obtenho:

$ 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}

Observe como run , --rm , app , etc. são passados como argumentos separados em bash e como um único argumento em zsh .

Isso porque bash dividiu e reduziu a variável $* em vários argumentos usando espaços (o valor padrão de IFS ) como delimitador. O mesmo efeito pode ser obtido em zsh usando $=* em vez de $* ou pela opção set -o SH_WORD_SPLIT , mas isso tornará o script somente zsh.

Você deve usar "$@" em vez de $* em todos os lugares, a menos que tenha uma razão muito especial para não:

compose() { docker-compose "$@"; }
run() { compose run --rm app "$@"; }
rails() { run rails "$@"; }
    
por 22.10.2018 / 18:57

Tags