这个shell脚本行有什么问题?

时间:2011-05-12 19:12:54

标签: bash shell

我有一个名为$ JOB_COMMAND的shell var,它具有启动map reduce作业的命令,如下所示:

user@server:/scriptpath# echo $JOB_COMMAND
/var/elastic-mapreduce/elastic-mapreduce --create 
    --name 'Extrabux-MapReduce' 
    --num-instances 16 --instance-type c1.medium --key-pair extrabux-keypair 
    --log-uri s3n://extrabux-log/
    --bootstrap-action "s3://extrabux-scripts/startup.sh" |
    egrep -o 'j-[a-zA-Z0-9]+'

显然,问题的重点并不需要很多这些选项,但是在某些可能的情况下,内容会影响答案,包括在内。

现在当我尝试从变量运行命令时,我得到了这个:

user@server:/scriptpath# $JOB_COMMAND
Error: --output must follow one of --streaming

但是,如果我复制并粘贴回显命令的结果,那么我得到以下内容:

user@server:/scriptpath#  /var/elastic-mapreduce/elastic-mapreduce --create 
    --name 'Extrabux-MapReduce' 
    --num-instances 16 --instance-type c1.medium --key-pair extrabux-keypair 
    --log-uri s3n://extrabux-log/
    --bootstrap-action "s3://extrabux-scripts/startup.sh" |
    egrep -o 'j-[a-zA-Z0-9]+'

j-3FV0MT3H7G21S

如您所见,该命令运行并成功吐出作业ID

以下是我想要做的事情,将作业ID转换为另一个shell var:

user@server:/scriptpath# JOBID=`$JOB_COMMAND`

任何想法为什么在var内部运行命令都会破坏? 仅供参考,我也尝试了

user@server:/scriptpath# JOBID=$($JOB_COMMAND)

这也给了我错误

感谢您的帮助!

3 个答案:

答案 0 :(得分:3)

问题是管道的解析(示例中的|)在扩展变量$JOB_COMMAND之前发生。在Bash中,首先解析行,然后扩展变量,基于$IFS拆分,并替换为命令。所以在你的命令中,| egrep及其后面的所有内容都作为文字参数传递给你的elastic-mapreduce命令;关于--output的错误可能是由-o参数引起的。

正如Bash FAQ指出的那样,你不应该在变量中存储命令,而是应该使用shell functions

job_command () {
    /var/elastic-mapreduce/elastic-mapreduce --create \
        --name 'Extrabux-MapReduce' \
        --num-instances 16 --instance-type c1.medium --key-pair extrabux-keypair \
        --log-uri s3n://extrabux-log/ \
        --bootstrap-action "s3://extrabux-scripts/startup.sh" | \
        egrep -o 'j-[a-zA-Z0-9]+'
}

现在您可以按如下方式调用它:

JOBID=$(job_command)

使用shell函数还允许您将参数传递给您的命令,您可能会觉得这些参数很有用。

如果您确实想要出于某种原因在变量中存储命令,则需要使用eval,但不建议这样做:

eval $JOB_COMMAND

答案 1 :(得分:2)

管道不起作用。将其拆分为两个命令。哦,还有BASH FAQ entry #50

答案 2 :(得分:0)

如果

,将具有更高的可读性(和功能性)
RESULT=`$JOB_COMMAND $JOB_ARGS | egrep ....`