I have bash script (named main.sh). Which looks something like:
#!/usr/bin/env bash
java -jar some.jar --test='{"prop": "My best 'app'"}'
When I run this bash script. I get:
bash -x main.sh
java -jar some.jar '--test={"prop": "My best app"}'
The single quotes around app are missing. How can I modify this bash script such that the single quotes around app are preserved?
I did check this question: Escape single quote within double quote within single quote but it didnt solve my issue.
CodePudding user response:
Your linked question is for passing the problematic string via stdin. You want to pass the problematic string as an argument. But you can still use the answers from your linked question by reading stdin into a variable which you then use as an argument:
json=$(cat <<'EOF'
{"prop": "My best 'app'"}
EOF
)
java -jar some.jar --test="$json"
In above case, the $( )
removes the trailing newline after …}
. If you want to keep trailing newlines, you can use
IFS= read -rd '' json <<'EOF'
{"prop": "My best 'app'"}
EOF
java -jar some.jar --test="$json"
For your usecase, both should work.
CodePudding user response:
For obvious lexical issues, quotes can not nest. Therefore, in
'{"prop": "My best 'app'"}'
the first opening quote is closed by the quote immediately preceeding the word app, and after this a new single quote opens. The net effect is as if you had simply written
'{"prop": "My best app"}'
You first need to make up your mind, what arguments java is supposed to see. The first 3 elements of the argument vector (argv) java gets are obviously
java
-jar
some.jar
If you want to have the final argument to be
--test={"prop": "My best 'app'"}
you can call it as
java -jar some.jar --test={\"prop\": \"My best \'app\'\"}
Instead of worrying about "quotes inside quotes", simply write the string as you want to have it passed to the application, and escape any character with special meaning to the shell.