psql's \set command unable to save json file's content in a variable I am trying to below set command inside bash:

#!/bin/bash

psql -X -h localhost -U &lt;dbuser&gt; -d &lt;dbname&gt; &lt;&lt;EOF
CREATE TABLE cardtable(id SERIAL PRIMARY KEY, charcolumn VARCHAR(20) NOT NULL, cardcolumn JSON NOT NULL);

\set var `cat /tmp/jsonfile.json`
INSERT INTO cardtable(charcolumn, cardcolumn) VALUES ('USA', :'var');

EOF


Content of jsonfile.json:

{
    "OT": [
        {
            "CD": 40,
            "ED": "2013-12-23",
            "ID": [
                "daf52501-330a-48a-d40988fa7a-a8",
            ]
         }
     ]
}


for some reason, the content of "var" was just '{' !! As a result INSERT command treats it as if the json data is of in-correct format and throws a syntax error.

Can someone please help me in understanding why "\set" command is behaving like this?

FYI: same command when executed manually at the psql prompt ends successfully!!
There here-doc feature in bash treats backticks as command invocations, so it executes the cat /tmp/jsonfile.json, which wrongfully injects the json contents into the psql commands:


  If word is unquoted, all lines of the here-document are subjected to
  parameter expansion, command substitution, and arithmetic expansion,
  the character sequence \newline is ignored, and ‘\’ must be used to
  quote the characters ‘\’, ‘$’, and ‘`’.


You may quote the EOF word to remove all expansions, as in :

psql [...] &lt;&lt; 'EOF'
... psql script...
\set var `cat /tmp/jsonfile.json`
...
EOF


That's the safest method when you don't need to inject anything from bash into the here-doc script.

Or, if any kind expansion in the here-doc string is needed, the above-mentioned characters must be quoted with backslash, as in:

myfile="/tmp/jsonfile.json"

psql [...] &lt;&lt; EOF
... psql script...
\\set var \`cat $myfile\`
...
EOF