【问题标题】:How to do a proper double or triple bash quote escape?如何进行正确的双倍或三倍 bash 引号转义?
【发布时间】:2012-07-26 02:26:37
【问题描述】:
#!/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 之外的其他行。

【问题讨论】:

    标签: bash escaping quotes double-quotes


    【解决方案1】:

    虽然@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
    

    【讨论】:

    • 哇,答案很长。我重写了问题以使其更容易。我正在寻找一种单行解决方案,仅此而已。在这一行之外不需要修改的东西。
    • @votingmeisfree,恐怕你不能。您需要做的就是在${JVM_SUPPORT_RECOMMENDED_ARGS} 周围包含\"。这不可能吗?!
    • 原因是,bash 将你的变量扩展成不同的参数(即使变量本身有",参见上面的例子在参数5到9 .)。避免这种情况的唯一方法(据我所知)是将$VARIABLE 放在" 中使用。
    • 谢谢,我只建议尝试从解决方案中删除样板。大多数人都喜欢简短的答案;)
    • @votingmeisfree,感谢您的建议。我会重新整理答案。
    猜你喜欢
    • 2022-11-10
    • 1970-01-01
    • 2020-08-04
    • 2014-02-15
    • 2014-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    相关资源
    最近更新 更多