3

I have the following bash script:

#!/bin/sh
psql -U postgres -c "CREATE DATABASE test TEMPLATE template0;"

if [ $? -eq 0 ]; then
    echo OK
else
    if [ $? = 'ERROR:  database "test" already exists' ]; then
         echo OK
    else
         echo FAIL
    fi
fi

It's currently failing with the following error:

testbox:/tmp# sh test.sh 
ERROR:  database "test" already exists
FAIL

I'm not sure where I've gone wrong. I need it to return "OK" for this specific error. Any other errors should print out a FAIL. Can you tell me where I've gone wrong?

Thanks.

EDIT 1

I've modified the code to capture the output, not just rc:

#!/bin/bash

output=$(psql -U postgres -c "CREATE DATABASE test TEMPLATE template0;")
ret=$?

if [[ $ret -eq 0 ]]; then
    echo OK
else
    if [[ $output == 'ERROR:  database "test" already exists' ]]; then
         echo OK
    else
         echo FAIL
    fi
fi

But I get this error:

ERROR:  database "test" already exists
sh: ERROR:  database "test" already exists: unknown operand
FAIL
Happydevdays
  • 1,982
  • 5
  • 31
  • 57
  • 2
    `$?` represents just the integer exit code not the output of your `psql` command. You need to grab the output and check. – anubhava Dec 22 '16 at 15:22
  • @anubhava ok. can you give me an example? – Happydevdays Dec 22 '16 at 15:23
  • 1
    @Happydevdays: try adding `echo $?` immediately after the `psql` command, and you'll see what anubhava means (it'll just print a number, probably "1"). Then add a second `echo $?`, and you'll see that one print "0" because the first `echo` command succeeded, and therefore exited with a status code of 0. – Gordon Davisson Dec 22 '16 at 15:31

3 Answers3

5

$? represents just the integer exit code not the output of your psql command. You need to grab the output of psql command and check in if condition.

You can use:

#!/bin/bash

output=$(psql -U postgres -c "CREATE DATABASE test TEMPLATE template0;" 2>&1)
ret=$?

if [[ $ret -eq 0 ]]; then
    echo OK
else
    if [[ $output == *'already exists'* ]]; then
         echo OK
    else
         echo FAIL
    fi
fi
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • I've changed first line to `output=$(psql -U postgres -c "CREATE DATABASE test TEMPLATE template0;" 2>&1)` so that we capture stderr also from `psql` command – anubhava Dec 22 '16 at 15:30
  • 1
    That works now. Thank you. What can i google to better understand the "2>&1" at the end of the first line? – Happydevdays Dec 22 '16 at 15:35
  • `2>&1` redirects stderr to file descriptor `1` which is `stdout` – anubhava Dec 22 '16 at 15:37
  • 1
    @Happydevdays [The Linux Documentation Project](http://tldp.org/) is a great resource. [Beginner's guide](http://www.tldp.org/LDP/Bash-Beginners-Guide/html/Bash-Beginners-Guide.html). [Advanced guide](http://www.tldp.org/LDP/abs/html/abs-guide.html). And more specifically, [the I/O redirection topic you're asking about](http://www.tldp.org/LDP/abs/html/abs-guide.html#IO-REDIRECTION). – TTT Dec 22 '16 at 18:05
  • @anubhava I am having a similar issue but the `return code is always 0` `content=$(java -jar ${jarFilePath} -u ${username},${password} -n ${host} -c "${val_query}") rc=$?` If the `val_query` has any syntax issue then how can I capture the error – nmr Mar 23 '21 at 17:34
0

The $? will output an integer based on exit code of last command executed. when the database exists it will be 1 returned. Thats why your script is failing.

Farhad Farahi
  • 35,528
  • 7
  • 73
  • 70
0

A shorter way if checking if a database exists can be found here.

Based on that output you can create your database and return somehting meaningful.

jaiks
  • 486
  • 4
  • 9