1

I'm having issues parsing the outputs of a postgres sql query from bash script.

Here is the output from a command line query to postgres:

root@API:/home# psql -U postgres -h pgipaddress -c "SELECT 1 AS __ROW__ FROM pg_roles WHERE rolname='postgres'"
 __row__ 
---------
       1
(1 row)

Here is what the variable $userexists looks like before you look at the conditions:

__row__ --------- 1 (1 row)

Here are my attempts at string conditional checking:

userexists=$(psql -U postgres -h ${pgip} -c "SELECT 1 AS __ROW__ FROM pg_roles WHERE rolname='postgres'")
if [ "${userexists}" == "__row__\n---------\n1 \n(1 row)"* ] ; then
  printf "Database User exists\n"
else
  printf "Database User does not exists\n"
fi

userexists=$(psql -U postgres -h ${pgip} -c "SELECT 1 AS __ROW__ FROM pg_roles WHERE rolname='postgres'")
if [ "${userexists}" == "__row__ --------- 1 (1 row)"* ] ; then
  printf "Database User exists\n"
else
  printf "Database User does not exists\n"
fi

All result in database user does not exist.

4
  • 1
    Have you considered using --quiet -tA flags, which would reduce your output to just 1 and nothing else? Commented Nov 14, 2018 at 18:34
  • perfect works great. only problem is if the user does not exist postgres issues an error on the console. i tried redirecting errors to /dev/null but when i do that i dont get output anymore Commented Nov 14, 2018 at 18:37
  • 1
    How about using count()? Commented Nov 14, 2018 at 18:44
  • actually that error was separate. make this an answer and ill accept Commented Nov 14, 2018 at 18:47

1 Answer 1

1

The contents of userexists are likely to actually contain the linebreaks, but you probably checked the contents with an unquoted expansion:

# Assignment
$ userexists=' __row__
---------
       1
(1 row)'

$ echo "$userexists"  # Quoted expansion
 __row__
---------
       1
(1 row)

$ echo $userexists    # Unquoted expansion squashes whitespace
__row__ --------- 1 (1 row)

Additionally, if you want to compare two strings containing linebreaks with [ ... ], you can't use "\n" to insert a linebreak. ANSI-C escapes, $'\n', would work:

var='has
linebreak'
[ "$var" = $'has\nlinebreak' ] && echo 'Match'

prints Match. Two remarks: Bash will understand == when used in [ ], but it's not portable, so = is recommended. Also, [ ] doesn't support pattern matching, so the * at the end of your right-hand side won't do what you expect. [[ ]] and case can be used for pattern matching.

To avoid the whole problem in the first place, you can supply a few flags to psql, specifically:

  • --quiet – no informational output
  • -t – tuples only; no column names, result count footers etc.
  • -A – unaligned output (removes leading blank from line)

and the return from your command will be just 1 and you can compare with

if [ "$userexists" = 1 ]; then
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.