[英]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.