将命令存储在变量中;没有`eval`的实现

时间:2019-06-24 21:31:21

标签: shell eval

除了我不想使用eval之外,这与本post中的问题几乎完全相同。

简短的问题是,我想执行命令echo aaa | grep a,方法是先将其存储在字符串变量Command='echo aaa | grep a'中,然后不使用运行eval

在上面的帖子中,所选答案使用了eval。这对我也适用。我非常担心的是,下面有关于eval 警告,然后进行一些规避它的尝试。但是,它们都不能解决我的问题(本质上是OP)。我在下面对他们的尝试进行了评论,但是由于已经存在了很长时间,因此我认为最好使用eval,以的限制再次发布该问题。

具体示例

我想要的是一个shell脚本,当我高兴的时候它会运行我的命令:

#!/bin/bash
# This script run-this-if.sh runs the commands when I am happy
# Warning: the following script does not work (on nose)
if [ "$1" == "I-am-happy" ]; then
    "$2"
fi

$ run-if.sh I-am-happy [insert-any-command]

2 个答案:

答案 0 :(得分:3)

您的示例用法永远无法与分配一起使用,因为分配的范围仅限于当前流程及其子流程。因为没有理由尝试支持任务,所以事情突然变得容易得多了:

#!/bin/sh
if [ "$1" = "I-am-happy" ]; then
    shift; "$@"
fi

然后可以在以后使用所有常用技术来运行shell管道,例如:

run-if-happy "$happiness" \
  sh -c 'echo "$1" | grep "$2"' _ "$untrustedStringOne" "$untrustedStringTwo"

请注意,我们正在传递execve()系统调用一个包含六个元素的argv:

  • sh(要运行的shell;如果需要,请更改为bash等)
  • -c(告诉外壳程序以下参数是其运行的代码)
  • echo "$1" | grep "$2"sh解析的代码)
  • _(成为$0的常量)
  • ... shell变量untrustedStringOne包含的任何内容...(变成$1
  • ... shell变量untrustedStringTwo包含的任何内容...(变成$2

请注意,echo "$1" | grep "$2"是一个常量字符串-用单引号括起来,没有参数扩展或命令替换-并且将不受信任的值传递到填充的插槽中$1$2,在所评估代码的带外;对于eval可以给您带来什么安全性方面的任何提高,这都是必不可少的。

答案 1 :(得分:-3)

您始终可以通过管道传递到解释器,例如:echo $Command | bash