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

发布于 2024-11-07 09:05:37 字数 1298 浏览 0 评论 0原文

我有一个名为 $JOB_COMMAND 的 shell 变量,它具有启动映射缩减作业的命令,如下所示:

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)

,这也给了我错误,

谢谢您的帮助!

I have a shell var called $JOB_COMMAND that has the command to launch a map reduce job like so:

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]+'

Obviously lots of those options are not needed for the point of the question, but in some off chance the content affects the answer, it's included.

Now when I try to run the command from the variable, I get this:

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

However if I copy and paste the result of echoing the command like so I get the following:

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

As you can see, the command runs and successfully spits out a job id

Here is what I would like to do, get the job ID into another shell var:

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

Any idea why running the command when it is inside a var is breaking?
FYI, I have also tried

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

and that also gives me the error

Thanks for your help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

叫嚣ゝ 2024-11-14 09:05:37

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

正如 Bash FAQ 指出的那样,您不应该将命令存储在变量中,您应该使用 < a href="http://www.gnu.org/software/bash/manual/bashref.html#Shell-Functions" rel="nofollow">shell 函数 代替。

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

The problem is that the parsing of the pipeline (the | in your example) happens before the variable $JOB_COMMAND is expanded. In Bash, parsing the line happens first, then variables are expanded, split based on $IFS, and substituted into the commands. So in your command, the | egrep and everything following it are being passed as literal arguments to your elastic-mapreduce command; the error about --output is probably due to the -o argument.

As the Bash FAQ points out, you shouldn't be storing commands in variables, you should use shell functions instead.

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]+'
}

And now you can call it as follows:

JOBID=$(job_command)

Using shell functions would also allow you to pass parameters in to your command, which you may find to be useful.

If you really want to store a command in a variable for some reason, you will need to use eval, but this is not recommended:

eval $JOB_COMMAND
马蹄踏│碎落叶 2024-11-14 09:05:37

管道不是这样工作的。将其分成两个命令。哦,还有 BASH 常见问题解答条目 #50

Pipes don't work that way. Split it into two commands. Oh, and BASH FAQ entry #50.

乄_柒ぐ汐 2024-11-14 09:05:37

如果

RESULT=`$JOB_COMMAND $JOB_ARGS | egrep ....`

Will be much readable (and functional) if

RESULT=`$JOB_COMMAND $JOB_ARGS | egrep ....`
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文