【问题标题】:Bash Expression Evaluation Order on Command Line命令行上的 Bash 表达式评估顺序
【发布时间】:2012-02-25 16:38:13
【问题描述】:

背景:

我正在努力在 SGE 的作业提交程序 qSub 中并行快速调用 bash 命令行表达式。这样做时,我试图提交一个表达式(作为参数)以在另一个脚本中运行,如下所示:

./runArguments.sh grep foo bar.txt > output.txt

runArguments.sh 看起来像这样:

#!/bin/bash  
${1} ${2} ${3} etc....to 12

我的想法是我希望在脚本中评估“grep foo bar.txt > output.txt”...而不是在命令行上。在上面的示例中,“grep foo bar.txt”将在 runArguments.sh 执行期间进行评估,但输出重定向将在命令行上进行评估。我最终找到了一个使用“eval”的有效解决方案,如下所示,但我不明白为什么它有效。

问题

1) 为什么

./runArguments.sh eval "grep foo bar.txt > output.txt"

允许将 eval 和表达式作为参数,但是

./runArguments.sh $(grep foo bar.txt > output.txt)

在调用脚本之前在命令行上进行评估? (将 $(grep...) 的输出作为参数)

2) 有更好的方法吗?

提前致谢!

【问题讨论】:

    标签: bash shell eval arguments


    【解决方案1】:

    您的第一个问题有点难以回答,因为您自己已经回答过了。如您所见,命令替换($(...)`...` 表示法)替换命令的输出,然后处理结果。例如,这个:

    cat $(echo tmp.sh)
    

    转换成这个:

    cat tmp.sh
    

    所以在你的情况下,这个:

    ./runArguments.sh $(grep foo bar.txt > output.txt)
    

    运行grep foo bar.txt > output.txt,获取它的输出——这没什么,因为你已经将任何输出重定向到output.txt——并替换它,产生:

    ./runArguments.sh
    

    (因此您的脚本在没有参数的情况下运行)。

    相比之下,这个:

    ./runArguments.sh eval "grep foo bar.txt > output.txt"
    

    不执行任何命令替换,因此您的脚本使用两个参数运行:evalgrep foo bar.txt > output.txt。脚本中的这个命令:

    ${1} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} ${10} ${11} ${12}
    

    因此等价于:

    eval grep foo bar.txt '>' output.txt
    

    它使用五个参数调用 eval 内置函数:grepfoobar.txt>output.txt。内置的eval 将其参数组装成一个命令,并运行它们,甚至将>output.txt 参数转换为一个输出重定向,所以上面的等价于:

    grep foo bar.txt > output.txt
    

    。 . .你已经知道那是做什么的了。 :-)


    至于你的第二个问题——不,没有更好的方法来做到这一点。您需要将> 作为参数传入,这意味着您需要使用eval ...bash -c "..." 等才能将其“翻译”回输出重定向的含义。如果你没事的话修改脚本,那么你可能想改变这一行:

    ${1} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} ${10} ${11} ${12}
    

    到这里:

    eval ${1} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} ${10} ${11} ${12}
    

    这样你就不需要在参数中处理这个了。或者,实际上,您不妨将其更改为:

    eval ${@}
    

    这会让你传入超过十二个参数;或者,更好的是:

    eval "${@}"
    

    这将使您稍微更好地控制分词和文件通配等等。

    【讨论】:

    • eval ${@} 提示非常有用,谢谢。我仍然不清楚为什么在命令输入期间不评估 eval 。它有点像操作顺序概念吗?例如,bash 是否会 1) 命令替换 2) 执行带参数的脚本 3) 评估 eval ...等?是否正在运行类似于 [eval
    • @sequenceGeek:没有理由在命令输入期间评估eval 。你知道命令echo cat foo 只是打印出文本cat foo,而不是运行程序cat?因为echo 是命令,而cat 只是参数之一。好吧,eval 也不例外:它在运行时有一些有趣的行为,但就像任何其他命令一样,它只在它是命令中的第一个单词时运行。
    猜你喜欢
    • 1970-01-01
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多