背景
我正在努力快速调用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”的工作解决方案,如下所示,但我不明白为什么它可以工作。
问题(S)
1)为什么
./runArguments.sh eval "grep foo bar.txt > output.txt"
允许将eval和表达式作为参数,但
./runArguments.sh $(grep foo bar.txt > output.txt)
在调用脚本之前评估命令行? (取而代之的是$(grep ...)的输出作为参数)
2)有更好的方法吗?
提前致谢!
答案 0 :(得分:3)
你的第一个问题有点难以回答,因为你已经自己回答了。如您所见,命令替换($(...)
或`...`
表示法)替换命令的输出,然后处理结果。例如,这个:
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"
不执行任何命令替换,因此您的脚本使用两个参数运行:eval
和grep 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
内置函数:grep
,foo
,bar.txt
,>
和output.txt
。 eval
内置将其参数组装成一个命令,并运行它们,甚至将>
和output.txt
参数转换为输出重定向,因此上述内容等同于:
grep foo bar.txt > output.txt
。 。 。而你已经知道那是做什么的。 : - )
关于你的第二个问题 - 不,没有更好的方法来做到这一点。您需要将>
作为参数传递,这意味着您需要使用eval ...
或bash -c "..."
等来将其“翻译”回意义输出重定向。如果你是O.K.修改脚本,然后您可能想要更改此行:
${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 ${@}
将允许您传递超过12个参数;或者,更好的是,这个:
eval "${@}"
这会让你稍微更多地控制分词和文件播放等等。