巴什前pression计算顺序的命令行 [英] Bash Expression Evaluation Order on Command Line
问题描述
背景:
我赶紧努力呼吁并行SGE的作业提交方案QSUB内bash命令行前pressions。虽然这样做,我试图提交前pression(作为参数),另一个脚本内将跑,像这样:
I'm working on quickly calling bash command line expressions inside of SGE's job submission program qSub in parallel. While doing so, I was attempting to submit an expression (as an argument) to be ran inside of another script like so:
./ runArguments.sh的grep富跳回到bar.txt> output.txt的
./runArguments.sh grep foo bar.txt > output.txt
runArguments.sh 的是这样的:
runArguments.sh looks like this:
#!/bin/bash
${1} ${2} ${3} etc....to 12
的想法是,我想要的grep富跳回到bar.txt> output.txt的脚本进行评估......不是在命令行。在上面的例子中,grep的富跳回到bar.txt将runArguments.sh执行期间评估,但输出重定向将在命令行上进行评估。我终于找到使用如下图所示EVAL工作解决方案,但我不明白的为什么的工作原理。
问题(S)
1)为什么
./runArguments.sh eval "grep foo bar.txt > output.txt"
允许的eval和前pression将被视为参数,但
allow the eval and the expression to be taken as arguments, but
./runArguments.sh $(grep foo bar.txt > output.txt)
在命令行上评估脚本调用之前? ($(grep的...)的输出被作为替代参数)
evaluates on the command line before the script is called? (the output of $(grep...) is taken as the arguments instead)
2)是否有这样做的更好的办法?
2) Is there a better way of doing this?
在此先感谢!
推荐答案
您的第一个问题是有点难以回答,因为你已经回答了你自己。正如你所看到的,命令替换(即 $(...)
或``...
符号)替代的命令的输出,然后处理结果。例如,这
Your first question is a bit hard to answer, because you've already answered it yourself. As you've seen, command substitution (the $(...)
or `...`
notation) substitutes the output of the command, and then processes the result. For example, this:
cat $(echo tmp.sh)
被转换为这样的:
gets converted to this:
cat tmp.sh
所以你的情况,这样的:
So in your case, this:
./runArguments.sh $(grep foo bar.txt > output.txt)
运行的grep富跳回到bar.txt> output.txt的
,抓住它的输出—这将是什么,因为你已经重定向任何输出到 output.txt的
—并替换它,产生:
runs grep foo bar.txt > output.txt
, grabs its output — which will be nothing, since you've redirected any output to output.txt
— and substitutes it, yielding:
./runArguments.sh
(所以你的脚本不带参数运行)。
(so your script is run with no arguments).
相比之下,这样的:
./runArguments.sh eval "grep foo bar.txt > output.txt"
不执行任何命令替换,所以你的脚本有两个参数运行:评估
和的grep富跳回到bar.txt> output.txt的
。你的脚本里面这个命令:
does not perform any command substitution, so your script is run with two arguments: eval
, and grep foo bar.txt > output.txt
. This command inside your script:
${1} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} ${10} ${11} ${12}
因此,相同的:
is therefore equivalent to this:
eval grep foo bar.txt '>' output.txt
该调用评估
内建有五个参数:的grep
,富
,跳回到bar.txt
,>
和 output.txt的
。在评估
内置组装它的参数到命令,并运行它们,甚至平移>
和 output.txt的
参数为输出重定向,所以上面是相同的:
which invokes the eval
built-in with five arguments: grep
, foo
, bar.txt
, >
, and output.txt
. The eval
built-in assembles its arguments into a command, and runs them, and even translates the >
and output.txt
arguments into an output-redirection, so the above is equivalent to this:
grep foo bar.txt > output.txt
。 。 。你已经知道做什么。 : - )
. . . and you already know what that does. :-)
至于你的第二个问题—没有,有没有一个真正的更好的方式来做到这一点。你需要通过>
作为参数,这意味着你需要使用评估...
或的bash -c...
或以翻译它放回意思输出重定向等。如果你O.K.与修改脚本,那么你可能要改变这一行:
As for your second question — no, there's not really a better way to do this. You need to pass the >
in as an argument, and that means that you need to use eval ...
or bash -c "..."
or the like in order to "translate" it back into meaning output-redirection. If you're O.K. with modifying the script, then you might want to change this line:
${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}
,这样你就不需要在参数来处理这个问题。或者,其实,你不如改成这样:
so that you don't need to handle this in the parameters. Or, actually, you might as well change it to this:
eval ${@}
这将让你在超过十二参数传递;或者,更好的做法是:
which will let you pass in more than twelve parameters; or, better yet, this:
eval "${@}"
这将给你的略的过字分裂和fileglobbing和诸如此类的东西更多的控制。
which will give you slightly more control over word-splitting and fileglobbing and whatnot.
这篇关于巴什前pression计算顺序的命令行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!