In my script there's:
#!/bin/bash
# Take sudo password from the first argument if present
SUDO="sudo -u postgres"
if [ "$1" != "" ]; then
SUDO="echo $1 | sudo -S -u postgres"
fi
${SUDO} psql -c "create database foo;"
... several other similar commands here ...
When I run the script with myPassword
I get:
myPassword | sudo -S -u postgres psql -c create database foo;
So it just echoes the line. Obviously what I want is to literally run that command, but so that $1
gets expanded:
$ echo myPassword | sudo -S -u postgres psql -c create database foo;
How can I do that?
Pipes |
, redirection <
and stuff like that are not interpreted by the shell when you run a command by expanding a variable. Only words are split and globs (*
, ?
, []
) are expanded. Example:
$ v='echo a | cat'
$ $v
a | cat > b
To interpret them, you could use eval
$ v='echo a | cat'
$ eval "$v"
a
However, this is frowned upon as you often end up with quoting issues. Usually, there are better ways to solve a specific problem.
As a somewhat cleaner solution you could wrap your pipe inside a function:
#!/bin/bash
# Take sudo password from the first argument if present
SUDO="sudo -u postgres"
if [ "$1" != "" ]; then
pw="$1"
sudoWithPw() { echo "$pw" | sudo -S -u postgres "$@"; }
SUDO="sudoWithPw"
fi
${SUDO} psql -c "create database foo;"
An even better solution would be to login as user postgres
only once instead of prefixing every command with ${SUDO}
. You can do so using su
or sudo bash -c aFunctionYouExportedEarlier
.