如何在 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

如何强制 shell 像 bash 一样再次解析变量值?

答案1

如果您想要一个扩展为多个参数的变量,请使用数组:

var=(ls -l)
$var

但要存储代码,最明显的存储类型是函数:

myfunction() ls -l

或者:

myfunction() ls -l "$@"

让该函数接受额外的参数传递给ls.

bash与大多数其他类似 Bourne 的 shell 一样,在扩展时拆分未加引号的变量这一事实在我看来是一个错误。看它导致的问题类型。但如果您想要这种行为,您可以设置该shwordsplit选项。您还可以添加globsubst恢复另一个选项漏洞在其他类似 Bourne 的 shell 中发现bash,其中变量扩展也受到通配符(又名路径名扩展)的影响。或者使用emulate shor执行完整的 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 在扩展变量时使用分词。

相关内容