How to list databases owned by rolename in postgresql - bash

The code i tried in bash executed by root.
#!/bin/bash
su - postgres <<EOF1
F="$(psql -d postgres --tuples-only -P format=unaligned -c "SELECT datname FROM pg_database JOIN pg_authid ON pg_database.datdba = pg_authid.oid WHERE rolname = 'username'")"
EOF1
echo $F
It gives output as
ERROR: permission denied for relation pg_authid
But when i try
su - postgres <<EOF1
psql -d postgres --tuples-only -P format=unaligned -c "SELECT datname FROM pg_database JOIN pg_authid ON pg_database.datdba = pg_authid.oid WHERE rolname = 'username'"
EOF1
This prints all db of that username. Why so?
I need to store the ouput to a bash variable for further processing.
Is there any mistake or anyother way to try this out..
Thanks.

The inner $(...) expression gets executed before the su part, so it will not be run as postgres but as the current user. This is probably better written as:
command="psql -d postgres --tuples-only -P format=unaligned -c \"SELECT datname FROM pg_database JOIN pg_authid ON pg_database.datdba = pg_authid.oid WHERE rolname = 'username'\""
F=$( su - postgres -c "$command" )
You could put it all together, however:
F=$( su - postgres -c "psql -d postgres --tuples-only -P format=unaligned -c \"SELECT datname FROM pg_database JOIN pg_authid ON pg_database.datdba = pg_authid.oid WHERE rolname = 'username'\"" )
I should also note that the first example that failed for you probably would not set F to anything you could read outside of the su. However, Ubuntu and I presume other modern Linux systems do not allow you to use su in this way. You should use, e.g., sudo -l -u postrges and configure /etc/sudoers appropriately for people to have permission to run psql or whatnot as the postgres user.

Related

Ways to add one more quote nesting level (docker + bash + psql)

I need to modify a value in postgreSQL table in docker using a single command. I want to run something like this inside a container:
su - postgres -c "psql -c \"\c database_name\" -c \"UPDATE table_name SET value_name = 'value';\""
It turned out to be the only way to do this because echo "\c database_name \\ UPDATE table_name SET value_name = 'value';" | psql doesn't work in my postgreSQL resulting in
invalid command \
Is there anything I can do to run it in a container via command sudo docker exec -it container_name bash -c "*command above*"? None of the quote types surrounding command above make it work. Thank you in advance!
You should be able to avoid using su by telling docker exec itself which user should run psql. You can also run psql directly, rather than executing a bash shell that executes it.
sudo docker exec --user postgres \
psql -c "\c database_name" -c "UPDATE table_name SET value_name = 'value';"

Adding psql in shell script

I have this code $(echo "psql -U postgres -d mydb -c "SELECT * FROM table_name;" " | ssh $REMOTE_IP)
I need to run that query in the remote host, but i can't apply the query part in the echo
Any help?
Your syntax is incorrect and you don't need to use pipe. Try this:
ssh "$REMOTE_IP" 'psql -U postgres -d mydb -c "SELECT * FROM table_name;"'

Why does vagrant ssh -c ignore single quotes in command?

I want to update a column of my database running in a VW (using Vagrant) with the host's IP.
To do this I want to use a bash script:
LOCAL_IP=$(ipconfig getifaddr en0)
SQL="vagrant ssh -c 'psql -U user -d mydatabase -h localhost -c \"update mytable set mycolumn = '$LOCAL_IP';\"'"
eval $SQL
But I get this error:
ERROR: syntax error at or near ".123"
LINE 1: update mytable set mycolumn = 123.123.123.123;
The ouput of the SQL vriable:
echo $SQL
vagrant ssh -c 'psql -U user -d mydatabase -h localhost -c "update mytable set mycolumn = '123.123.123.123';"'
When I call the psql command from echo $SQL in the vm everything is fine, but I don't have the host ip.
vagrant ssh
psql -U user -d mydatabase -h localhost -c "update mytable set mycolumn = '123.123.123.123';"
It looks like the vagrant ssh -c command would remove the single quotes around the IP. Any ideas?
UPDATE
Easiest way to reproduce my problem:
$ vagrant ssh -c 'echo "update table set column = 'test';" > bla.sql'
$ vagrant ssh
$ cat bla.sql
update table set column = test;
I found the solution here:
https://stackoverflow.com/a/20498919/5902456
It looks now like this:
SQL="vagrant ssh -c 'psql -U user -d mydatabase -h localhost -c \"update mytable set mycolumn = '\''$LOCAL_IP'\'';\"'"

bash script returns error "ERROR: syntax error at end of input LINE 1: SELECT" for psql request to copy the table to an external file

What should I do for making it work?
#!/bin/bash
TABLENAMES="user_stats"
ssh -t railsapps#xxx.xxx.xxx.xx -p xxx bash -c "'
for TABLENAME in $TABLENAMES
do
psql -d mydb -P format=unaligned -P tuples_only -P fieldsep=\, -c "SELECT * FROM $TABLENAME" > /tmp/$TABLENAME
done
'"
General problem: how to periodically dump the database tables to a local machine from a psql database in a single bash script run on Mac OS X?
Firstly, you should test your SQL and bash scripts remotely (do SSH interactively).
I think your problem is caused by a bad mix of quote / double-quote. I think the star (*) and $TABLENAME are expensed before the SSH call, so too early. Try to put a backslash before the $ sign.
You should use the verbose or the debug option, to help to understand what is really executed:
ssh -t railsapps#xxx.xxx.xxx.xx -p xxx bash -vxc "'
for TABLENAME in \$TABLENAMES; do
psql -d mydb -P format=unaligned -P tuples_only -P fieldsep=\, -c "SELECT \* FROM \$TABLENAME" > /tmp/\$TABLENAME
done
'"

store postgresql result in bash variable

How to atore a scalar postgresql-value on a bash-variable like in script below?
dbname="testlauf"
username="postgres"
vartest='psql -c -d $dbname -U $username -h localhost -p 5432 "SELECT gid FROM testtable WHERE aid='1';"'
echo "$vartest"
I tried several different writings, but nothing seems to work. Thanks in advance.
Put the -c option just before its argument - the query. Mind also using the additional -t option to get just the tuple value. And of course, use the backticks (`) operator.
Using the -X option is also recommended, as sometimes a .psqlrc file might add some redundant output, as well as the -A option, which disables column aligning (whitespaces).
In order to skip NOTICE or other additional messages, include the -q flag.
vartest=`psql -d $db -U $user -AXqtc "SELECT gid FROM testtable WHERE aid='1'"`
Using -t option or --tuples-only will give you the rows only, so it will easier to store them in array variable (if the result from query more than one)
vartest =(`psql -t -d $dbname -U $username -c "SELECT gid FROM testtable WHERE aid='1';"`)
echo $vartest
example:
query result
ubuntu#ratnakri:~$ psql -h localhost -p 5432 -t -U postgres -d postgres -c "select slot_name from pg_replication_slots"
barman
barman2
make it into array variable
ubuntu#ratnakri:~$ RESULT=(`psql -h localhost -p 5432 -t -U postgres -d postgres -c "select slot_name from pg_replication_slots"`)
ubuntu#ratnakri:~$ echo ${RESULT[0]}
barman
ubuntu#ratnakri:~$ echo ${RESULT[1]}
barman2

Resources