I am creating a script to configure a server from scratch, part of this is postgres. One of the issues I'm having is if a random password has an exclamation it seems to be expanded by bash:

I want run the following postgres command:

alter user root with encrypted password 'D1£example!2eNZY6P$9examplePassword';

But from bash script using:

psql -c "command;"


runuser -l postgres -c "above cammand"

So I get this:

psqlcmd1="psql -c \"""alter user root with encrypted password 'D1£LF1A\!2eNZY6P$9examplePassword';""\""
runuser -l postgres -c "$psqlcmd1"

But bash expands the ! even though its between single quotes?

Also, I had tried the following based on this to escape the single quotes without luck :

runuser -l postgres -c "psql -c 'alter user root with encrypted password '"'"'D1£example!2eNZY6P$9examplePassword'"'"';'"
  • 1
    Let me parse that: "psql -c \"" quote/unquote, then "alter user root with encrypted password 'D1£LF1A\!2eNZY6P$9examplePassword';" - another quote/unquote. So your ! is actually in double quotes, not single.
    – muru
    Sep 23, 2015 at 10:37
  • 1
    So the effects of single quotes are negated when within double quotes?
    – ZZ9
    Sep 23, 2015 at 10:38
  • 2
    Yes. Try echo "'$SHELL'".
    – muru
    Sep 23, 2015 at 10:39

1 Answer 1

psqlcmd1="psql -c \"""alter user root with encrypted password 'D1£LF1A\!2eNZY6P$9examplePassword';""\""

With history expansion turned off, the value of psqlcmd1 is

psql -c "alter user root with encrypted password 'D1£LF1A\!2eNZY6PexamplePassword;"

Inside double quotes, the only characters that don't stand from themselves are \"$`, plus ! if history expansion is enabled. Note in particular that ' inside double quotes stands for itself: it doesn't start a string literal, the double quotes have already started one. Also note that since $ starts a variable expansion, $9 is expanded; its value is the 9th parameter to the current script of function, empty if there were fewer than 9 parameters.

Also note that "foo""bar" is the same thing as "foobar": it's two string literals joined together, so it might as well be written as a single string literal.

Inside double quotes, you need to put a backslash before the characters \"$` if you want the resulting string to include that character. This doesn't work for !: "!" is the string ! in a script, but invokes history expansion if that is enabled; "\!" is always the string \!. You need to use single quotes or no quotes around the !. Simplest would be to use a single-quoted literal: all characters inside single quotes stand for themselves, except for single quotes. To include a single quote in a single-quoted literal, end the literal, then use a backlash to quote a single quote, and start a single-quoted literal; or in other words, to include a single quote in a single-quoted literal, write '\''.

psqlcmd1='alter user root with encrypted password '\''D1£example!2eNZY6P$9examplePassword'\'';'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.