cod*_*oet 5 shell bash zsh shell-script function
是否可以将变量传递给 zsh 函数,并在不使用 eval 的情况下修改其值?我遇到了一种 bash 方法来做到这一点:: https local -n
: //stackoverflow.com/a/50281697
typeset -n
实际上最初来自 ksh93 (1993)。bash 在 2014 年发布的 4.3 中添加了类似的内容。在 ksh93 中,它更有用,因为 ksh93 执行静态作用域(您无法从调用者访问局部变量,除非它们被导出),而不是 bash 中的动态作用域/zsh (其中函数始终看到其调用者\xc2\xb9 的局部变量)。也可以看看:
$ bash -c \'function f { typeset -n var=$1; var=x;}; var=0; f var; echo "$var"\'\nenvironment: line 0: typeset: warning: var: circular name reference\nenvironment: warning: var: circular name reference\nenvironment: warning: var: circular name reference\nx\n$ ksh -c \'function f { typeset -n var=$1; var=x;}; var=0; f var; echo "$var"\'\nx\n
Run Code Online (Sandbox Code Playgroud)\nzsh 没有 nameref 支持,尽管它有变量取消引用运算符,可用于扩展和赋值。
\n$ expand() print -r -- ${(P)1}\n$ assign() : ${(P)1::=$2}\n$ var=foo\n$ expand var\nfoo\n$ assign var bar\n$ print -r -- $var\nbar\n
Run Code Online (Sandbox Code Playgroud)\n或者您始终可以使用标准方法,eval
该方法应该在任何类似 Bourne 的 shell 中工作:
expand() {\n eval \'printf "%s\\n" "${\'"$1"\'}"\'\n}\nassign() {\n eval "$1=\\$2"\n}\n
Run Code Online (Sandbox Code Playgroud)\n在你问之前,不,这并不比P
在 bash 中使用标志或 namerefs 更不安全,只要它像这里一样正确完成。无论采用哪种方法,正确控制变量名称都很重要。
assign var "$external_input"
无论您使用、 namerefs 还是 ,assign "$external_input" value
是否安全。与with或which相同,都是bash/ksh/zsh 中的任意命令执行漏洞。expand "$external_input"
P
eval
[ -v "$external_input" ]
read "$external_input"
另请参阅zsh-workers 邮件列表上关于进行间接分配的各种方法的优点的讨论。
\n2001 年的讨论正在考虑向 zsh 添加 ksh93 风格的 nameref 支持。2015 年和 2023 年再次出现,表明人们有兴趣添加该功能,并且最终可能会在 5.9 之后的下一个版本中添加该功能,无论是 5.10 还是 6.0 。
\n\xc2\xb9 尽管请参阅zsh/param/private
模块zsh
以将变量变为函数私有。
归档时间: |
|
查看次数: |
1187 次 |
最近记录: |