繁体   English   中英

是否有任何替代方法可以在 shell 脚本中使用 eval 来实现变量扩展

[英]Is there any alternative to using eval in a shell script to achieve variable expansion

我有以下情况,其中 exec 和 eval 将以不同的方式处理作为 arguments 传递的变量。 在这里, eval 似乎 output 是有意的。

但是有没有其他方法可以使用它?

$ cat arg.sh 
#!/bin/bash

eval ./argtest $*

$ ./arg.sh "arg1 'subarg1 subarg2'"
Args: 2
Arg1: arg1
Arg2: subarg1 subarg2

但同时,如果我使用 exec 而不是 eval 调用,则单引号不会得到尊重。

$ ./arg.sh "arg1 'subarg1 subarg2'"
Args: 3
Arg1: arg1
Arg2: 'subarg1
Arg3: subarg2'

应该这样做:

#!/bin/bash    
./argtest "$@"

正确通过未更改的 arguments。

然后做:

$ ./arg.sh arg1 'subarg1 subarg2'

正如您对任何其他命令所做的那样。

研究何时在 shell 中使用引号, $@位置 arguments 扩展如何在引号中特别处理,研究$*$@如何不同并研究分词。 还要研究什么是变量扩展,它发生在什么上下文中以及单引号与双引号有何不同。 并且因为提到了 exec,请参阅bashfaq Eval 命令和安全问题 请记住使用https://shellcheck.net检查您的脚本。

是否有任何替代方法可以在 shell 脚本中使用 eval 来实现变量扩展

是的 - 使用envsubst进行变量扩展,它只是一个工具。

#!/bin/bash
arg=$(VARIABLE=something envsubst '$VARIABLE' <<<"$1")
./argtest "$arg"

$ bash -x ./arg.sh 'string with **not-expanded** $VARIABLE'
+ ./argtest 'string with **not-expanded** something'

是否有任何替代方法可以在 shell 脚本中使用 eval 来实现*单引号解析

是的-您可能会编写自己的解析器,可能在awk中,它将拆分字符串然后重新加载。 一个非常粗略的例子:

#!/bin/bash
readfile -t args < <(sed "s/ *'\([^']*\)' */\n\1\n/; s/\n$//" <<<"$*")
./argtest "${args[@]}"

$ bash -x ./arg.sh  "arg1 'subarg1 subarg2'"
+ ./argtest 'arg1' 'subarg1 subarg2' 

使用 $*,shell 对参数应用分词,并将分词后的效果传递给eval , repsepcitvely exec 之后会发生什么,它们之间有所不同:

exec只是根据它获得的第一个参数,用一个新进程替换当前进程。 比 in 将未修改的剩余参数传递给此过程。

另一方面, eval将参数连接到一个字符串(使用一个空格作为这些字符串之间的分隔符),然后将此结果字符串视为一个新命令,其中应用了bash的通常扩展和分词机制,最后运行这个命令。

机制完全不同,这并不奇怪,因为这些命令用于不同的目的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM