Bash – How does this su -c “…” command seem to pass two commands instead of one

bashshell-scriptsu

I am trying to understand the script below and I am confused about the su line. I understand the postgres command line arguments.

when I do man su the manual says

-c, –command=COMMAND
pass a single COMMAND to the shell with -c

However the line with the su - postgres -c ... seems to contain two commands

  • first one setting the LD_LIBRARY environment variable
  • second one calling pg_ctl

So are there two commands being passed with -c or one ?

start()
{
        echo $"Starting PostgreSQL 9.1: "
        su - postgres -c "LD_LIBRARY_PATH=/opt/PostgreSQL/9.1/lib:$LD_LIBRARY_PATH /opt/PostgreSQL/9.1/bin/pg_ctl -w start -D \"/opt/PostgreSQL/9.1/data\" -l \"/opt/PostgreSQL/9.1/data/pg_log/startup.log\""

        if [ $? -eq 0 ];
        then
                echo "PostgreSQL 9.1 started successfully"
                exit 0
        else
                echo "PostgreSQL 9.1 did not start in a timely fashion, please see /opt/PostgreSQL/9.1/data/pg_log/startup.log for details"
                exit 1
        fi
}

Best Answer

It's a single command passed to the shell. The shell allows you to set environment variables on a per-command basis, eg:

PGPORT=5433 psql

su invokes the shell with its argument, so:

su -c 'PGPORT=5433 psql'

is like doing:

su
exec bash -c 'PGPORT=5433 psql'

Frankly, I tend to prefer using sudo, which makes setting environment variables easy and handles commands with complex quoting properly because it doesn't go via the shell.

Related Question