如何做一个适当的双重或三重bash报价逃脱?

时间:2012-07-27 11:56:05

标签: bash escaping quotes double-quotes

#!/bin/bash
# this works: java '-XX:OnOutOfMemoryError=nohup bash -c "service jira stop;service jira stop" &' -version
JVM_SUPPORT_RECOMMENDED_ARGS="" # WHAT TO PUT HERE !?! so the last line will execute the command above?
JAVA_OPTS=" ${JAVA_OPTS} ${JVM_REQUIRED_ARGS} ${DISABLE_NOTIFICATIONS} ${JVM_SUPPORT_RECOMMENDED_ARGS} ${JVM_EXTRA_ARGS} ${JIRA_HOME_MINUSD}"
set -x
java $JAVA_OPTS -version

如果可能,请勿触摸除JVM_SUPPORT_RECOMMENDED_ARGS之外的其他行。

1 个答案:

答案 0 :(得分:5)

虽然@ raukh的答案是正确的,即你必须逃离",你也错过了另一个观点。

回答不耐烦的问题:您还需要在\"周围添加${JVM_SUPPORT_RECOMMENDED_ARGS},以防止bash将JVM_SUPPORT_RECOMMENDED_ARGS的内容分隔为不同的参数。


完整答案:

想象一下这个例子,假设print_args是一个程序,它在一行中回应它的参数

TEST="a b"
./print_args $TEST

这将输出ab作为单独的参数。这是因为删除了",实际上执行的命令是:

./print_args a b

要使您的命令将变量全部视为一个参数,您必须将其放入"

TEST="a b"
./print_args "$TEST"

a b显示为一个参数。

即使你在字符串中写了额外的",它也行不通,因为bash会分离变量的内容:

TEST="\"a b\""
./print_args $TEST

会将"ab"作为单独的参数。您可以处理此问题的唯一方法是在使用变量的位置添加",而不是在您定义变量的位置。

所以在你的情况下,解决方案是:

JVM_SUPPORT_RECOMMENDED_ARGS="java '-XX:OnOutOfMemoryError=nohup bash -c \"service jira stop;service jira stop\" &' test"
JAVA_OPTS=" ${JAVA_OPTS} ${JVM_REQUIRED_ARGS} ${DISABLE_NOTIFICATIONS} \"${JVM_SUPPORT_RECOMMENDED_ARGS}\" ${JVM_EXTRA_ARGS} ${JIRA_HOME_MINUSD}"

第一行是raukh建议的。第二行在\"附近添加了${JVM_SUPPORT_RECOMMENDED_ARGS}


如果你想测试一下,这是一个例子:

test.c:

#include <stdio.h>

int main(int argc, char **argv)
{
    int i;
    for (i = 0; i < argc; ++i)
        printf("%d: %s\n", i, argv[i]);
    return 0;
}

$ gcc -o print_args test.c

$ TEST="java '-XX:OnOutOfMemoryError=nohup bash -c \"service jira stop;service jira stop\" &' test"; ./print_args $TEST
0: ./print_args
1: java
2: '-XX:OnOutOfMemoryError=nohup
3: bash
4: -c
5: "service
6: jira
7: stop;service
8: jira
9: stop"
10: &'
11: test

$ TEST="java '-XX:OnOutOfMemoryError=nohup bash -c \"service jira stop;service jira stop\" &' test"; ./print_args "$TEST"
0: ./print_args
1: java '-XX:OnOutOfMemoryError=nohup bash -c "service jira stop;service jira stop" &' test