如何进行正确的双重或三重 bash 引号转义?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11687292/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 02:53:56  来源:igfitidea点击:

How to do a proper double or triple bash quote escape?

bashescapingquotesdouble-quotes

提问by sorin

#!/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

If possible don't touch other lines than the JVM_SUPPORT_RECOMMENDED_ARGS one.

如果可能,请不要触及 JVM_SUPPORT_RECOMMENDED_ARGS 以外的其他行。

回答by Shahbaz

Although @raukh's answer is right, i.e. you have to escape the ", you are also missing another point.

尽管@raukh 的回答是正确的,即您必须逃避",但您还错过了另一点。

Answer for the impatient: you need to add \"around ${JVM_SUPPORT_RECOMMENDED_ARGS}also, to prevent bash from separating the contents of JVM_SUPPORT_RECOMMENDED_ARGSto different argument.

不耐烦的回答:您还需要添加\"around ${JVM_SUPPORT_RECOMMENDED_ARGS},以防止 bashJVM_SUPPORT_RECOMMENDED_ARGS将不同参数的内容分开。



Complete answer:

完整答案:

Imagine this example, assuming print_argsis a program that echoes its arguments each in one line

想象一下这个例子,假设print_args有一个程序在一行中回显其参数

TEST="a b"
./print_args $TEST

This will output aand bas separate arguments. This is because the "is removed and in fact the executed command is:

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

./print_args a b

To make your command see your variable all as one parameter, you have to put it in ":

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

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

Will show a bas one argument.

将显示a b为一个参数。

Even if you write extra "in your string, it won't work, as bash will separate the contents of the variable anyway:

即使您"在字符串中写入额外内容,它也不会起作用,因为无论如何 bash 都会将变量的内容分开:

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

will give you "aand b"as separate arguments. The only way you can handle this, is to add "where you usethe variable, instead of where you define it.

会给你"ab"作为单独的论点。您可以处理此问题的唯一方法是添加"使用变量的位置,而不是您定义它的位置。

So in your case, the solution is this:

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

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}"

The first line is as raukh suggested. The second line has added \"around ${JVM_SUPPORT_RECOMMENDED_ARGS}.

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



If you want to test this, here is an example:

如果你想测试这个,这里有一个例子:

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