zshで変数にスペースがあるスクリプトを呼び出す方法は?

zshで変数にスペースがあるスクリプトを呼び出す方法は?

これはbashで期待どおりに機能します。

> t="ls -l"
> $t #== ls -l
> "$t" #== "ls -l"
ls -l: command not found

しかし、zshでは次のようになります。

> t="ls -l"
> $t #== "ls -l"
ls -l: command not found

シェルがbashのように変数の値を再解析するにはどうすればよいですか?

答え1

複数の引数に拡張される変数が必要な場合は、配列を使用してください。

var=(ls -l)
$var

しかし、コードを保存するための最も明確なストレージタイプは関数です。

myfunction() ls -l

または:

myfunction() ls -l "$@"

関数がに渡された追加の引数を受け入れるようにしますls

bash他のほとんどのBourne様シェルと同様に、引用されていない変数が拡張時に分割されるという事実がバグのようです。バラよりそれが引き起こす問題の種類。ただし、この動作が必要な場合は、このshwordsplitオプションを設定できます。globsubst復元に別のオプションを追加することもできます。抜け穴bashこれは、変数拡張がワイルドカード(パス名拡張とも呼ばれます)の影響を受ける他のBourne様シェルでも見られます。またはemulate sh完全なshebangを実行するには、またはを使用しますemulate ksh(しかし、より多くのzsh機能を失います)。

そこに行く必要はありません。zsh変数を明示的に分割することもできます。

var='ls -l'
$=var # split on $IFS like the $var of bash/sh
${(s[ ])var} # split on spaces only regardless of the value of $IFS
var='*.txt'
echo $~var # do pathname expansion like the $var of bash/sh
var='ls -ld -- *.txt'
$=~var # do both word splitting and filename generation

答え2

プロジェクト内容zsh よくある質問

簡単に言えば長い話です。この動作を解決する方法はいくつかあります。

  1. 置くsetopt shwordsplit:
setopt shwordsplit
t="ls -l"
$t
  1. 使用eval(可能なセキュリティ問題のために避けるのが最善):
t="ls -l"
eval $t

答え3

変数がすでに文字列として定義されている場合は、次のものを使用できます。

${=t}

この=フラグは、変数を拡張するときにトークン化を使用するようにzshに指示します。

関連情報