The safest way to pass commands to psql
in a script is by piping a string or passing a here-doc.
The man docs for the -c/--command
option goes into more detail when it should be avoided.
-c command
--command=command
Specifies that psql is to execute one command string, command, and then exit. This is useful in shell scripts. Start-up files (psqlrc and ~/.psqlrc)
are ignored with this option.
command must be either a command string that is completely parsable by the server (i.e., it contains no psql-specific features), or a single
backslash command. Thus you cannot mix SQL and psql meta-commands with this option. To achieve that, you could pipe the string into psql, for
example: echo '\x \\ SELECT * FROM foo;' | psql. (\\ is the separator meta-command.)
If the command string contains multiple SQL commands, they are processed in a single transaction, unless there are explicit BEGIN/COMMIT commands
included in the string to divide it into multiple transactions. This is different from the behavior when the same string is fed to psql's standard
input. Also, only the result of the last SQL command is returned.
Because of these legacy behaviors, putting more than one command in the -c string often has unexpected results. It's better to feed multiple
commands to psql's standard input, either using echo as illustrated above, or via a shell here-document, for example:
psql <<EOF
\x
SELECT * FROM foo;
EOF