[SOLVED] add literal string with simple and double quotes to a file
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
add literal string with simple and double quotes to a file
I'm trying to add the following string to a file:
Code:
sed 's|\$MYSQL_PASSWORD|'"$MYSQL_PASSWORD"'|'
I'm using the simple and double quote syntax so that sed would use the MYSQL_PASSWORD variable (in the second part; the first part is literally $MYSQL_PASSWORD) when sed is run in the file I'm trying to add the line to.
What I've tried to far is:
Code:
echo sed 's|\$MYSQL_PASSWORD|'"\$MYSQL_PASSWORD"'|' > file
But unfortunately it drops the quote altogether:
Code:
sed s|\$MYSQL_PASSWORD|$MYSQL_PASSWORD|
Somewhat closer is:
Code:
echo sed 's|\$MYSQL_PASSWORD|'"'"\$MYSQL_PASSWORD"'"'|'
But this drops the double quotes:
Code:
sed s|\$MYSQL_PASSWORD|'$MYSQL_PASSWORD'|
This is becoming a little bit retarded, so if there are more elegant solutions, I'm looking forward to it
Ok, I was actually able to find a horrible solution:
Code:
echo sed \''s|\$MYSQL_PASSWORD|'"'\""\$MYSQL_PASSWORD"'"\"'|'\'
But the question remains: is there any other way to achieve this?
Thanks!
Actually I made a mistake in the final result. It should have been:
Code:
echo sed \''s|\$MYSQL_PASSWORD|'"'\""\$MYSQL_PASSWORD\""'"'|'\'
I had misplaced the \ " (if I write \ " together, then the backslash is removed from the post, because it's interpreted as an escape character! )
I tested it by simply redirecting it into the file and it worked as expected:
Code:
root@oms:~# echo sed \''s|\$MYSQL_PASSWORD|'"'\""\$MYSQL_PASSWORD\""'"'|'\' > file
root@oms:~# cat file
sed 's|\$MYSQL_PASSWORD|'"$MYSQL_PASSWORD"'|'
is that sed interprets the ${MYSQL_PASSWORD} literally, because of the simple quotes. This is why I was trying to use '"$MYSQL_PASSWORD"' (so between simple + double quotes; so I'm escaping the bash variable that way and sed will replace it with the value of the variable, instead of the literal name).
Can you explain what the meaning of the angle brackets in echo ">${TEXT}<" is?
If any part of word is quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion
So your problem is that the password itself contains something which can be interpreted by sed.
You cannot protect it that way there is no fool-proof solution. You need to process the password string itself to escape all the suspicious chars.
> and < are just markers to see what is "inside". Nothing else.
I assume the file you're writing your sed expression to is a shell script. A reasonably recent bash should have a nice facility to cope with the problem pan64 describes in form of ${var@Q}. From the Bash Reference Manual:
Quote:
${parameter@operator}
The expansion is either a transformation of the value of parameter or information about parameter itself, depending on the value of operator. Each operator is a single letter:
Q
The expansion is a string that is the value of parameter quoted in a format that can be reused as input.
I assume the file you're writing your sed expression to is a shell script. A reasonably recent bash should have a nice facility to cope with the problem pan64 describes in form of ${var@Q}. From the Bash Reference Manual:
It is something new, somewhere bash 4.4 was implemented.
I wanted to restrict the thread only to this particular problem without giving the bigger context, but now the context has become much more relevant.
The point was to do something somewhat intentionally dumb, that is to say, to change an existing docker-entrypoint from an official docker image (of php-apache) through an additional Dockerfile, where I'd run the sed commands.
The here document would have been a great solution under normal circumstances, and it hadn't occurred to me anyway, but unfortunately it doesn't work in Dockerfile
What I did eventually (which I find much more sensible) was to actually copy only the entrypoint from github, add the sed lines that would replace the php configuration settings, and then copy it into the new image, ensuring, of course, that it has execution permissions (being an entrypoint).
@pan64
The issue with this: TEXT="sed 's|\$MYSQL_PASSWORD|${MYSQL_PASSWORD}|'" is that sed is not going to interpret the bash variable as it is, regardless of what the variable contains. This is why it needs to be escaped with '"${MYSQL_PASSWORD}"'. What the actual value of the variable is, is indeed a problem in itself and needs to be dealt with carefully, I agree, sure. That's why I chose a longer string (length of 40-50 characters) but with standard characters, as it were.
Anyway, thanks for the help, I've come away with lots of interesting information!
sed will never be able to use bash variables, that is a different language. https://stackoverflow.com/questions/...itution-in-sed
If you wish to do that you need to use perl/awk/python/... something, which can handle environment variables properly.
In that case the shell will evaluate $var and will pass the result to sed. As always, the command evaluated first (before execution). You can check it by executing set -x (before executing your sed)
Code:
$ set -x
$ var=cap
+ var=cap
$ echo "stuff" > file.txt
+ echo stuff
$ sed 's/stuff/'"$var"'/' file.txt
+ sed s/stuff/cap/ file.txt
cap
black was entered
blue was actually executed (after evaluation)
green is the result
Ok, I see what you mean (I also hadn't read the link entirely before answering), but that works for all intents and purposes. And that's the most important thing, so that's more of a theoretical problem (yes, not necessarily, because it depends on what the variable contains, but I've already cleared that up). There's no point in switching to another tool when doing such substitutions - they are being used widely.
the problem is when the variable contains something which can be interpreted by sed. And (if the content of the variable is unpredictable) this substitution is just unreliable.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.