2011-09-21 57 views
2

我在BASH脚本中使用调试模式来跟踪已由脚本执行的命令。到目前为止,这一切都工作得很好,但现在我需要运行一个命令,并在字符串中包含一些选项,并且该字符串包含引号,这些引号在调试模式下似乎会导致问题。BASH在调试模式下的报价

下面是一个简单的例子

#!/bin/bash 
job_opts='-q long -M5000000 -R"select[mem>5000] rusage[mem=5000]"' 
set -x 
bsub $job_opts # .... more options for job here 
set +x 

这个脚本生成使用BSUB命令提交给LSF作业队列但不应该的问题。 在STDERR我看到这个痕迹:

+ bsub -q long -M5000000 '-R"select[mem>5000]' 'rusage[mem=5000]"' 
Job submission rejected. 

的BSUB命令应该是这样的:

+ bsub -q long -M5000000 -R"select[mem>5000]' 'rusage[mem=5000]" 

所以我BSUB命令失败,我也可以看到,这是因为它没”请参阅-R开关,大概是因为整个开关附加了单引号。

我明白,BASH在调试模式下将单引号括在引号字符串中,但我没想到这会影响正在发布的实际命令,这似乎已经发生了。

我在这里做了些什么错误,或者有什么办法避免在BASH调试模式中引用这个额外的引用?以这种方式记录命令非常方便,如果因为那些讨厌的引号而不能再做它,那将是一种耻辱。

感谢您的帮助!

+1

调试模式不是造成问题的原因,它只是显示你会怎样无论如何都会发生:变量被替换时,不会分析变量值中的引号。 –

+0

当我在命令行上对job_opts进行赋值然后回显它时,它看起来都很好(没有多余的单引号)。只有当我接着“设置-x”然后再次回显时,才会看到添加的单引号。 – tospo

+0

'echo bsub -q long -M5000000'-R“select [mem> 5000]''rusage [mem = 5000]”'''也会*看起来*很好,但它不会是你想要的。 –

回答

5

你不能用普通变量来做这件事,shell会解析它来分离参数。你可以做的eval,但我不会推荐它:

eval bsub $job_opts 

你可以用一个数组做到这一点:http://mywiki.wooledge.org/BashFAQ/050

job_opts=("-q" "long" "-M5000000" '-R"select[mem>5000] rusage[mem=5000]"') 
bsub "${job_opts[@]}" 
+0

太好了,谢谢,阵列似乎是我需要的解决方案! – tospo