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 "$@"; }

関連情報