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;"'
Related
I am trying to create a shell script to bootstrap new DBs.
I am able to create users, grant privileges and do all actions, except running any queries with passwords. The single quotes in shell script creates statements which postgres is not accepting.
Because of this, we cannot completely automate this process.
Below is one of the postgres line used in shell script.
PGPASSWORD=change123 psql -h $DB -p 5432 -d postgres -U root -c \"CREATE USER $(echo "$j" | cut -d "_" -f1)dbuser WITH PASSWORD \'$(echo $DBPASSWD|base64 --decode)\';\"
When executing the above script, the command is converted as
psql -h testdb -p 5432 -d postgres -U root -c '"CREATE' USER admindbuser WITH PASSWORD ''\''ZnuLEmu72R'\'''
where I want the command to be like
psql -h testdb -p 5432 -d postgres -U root -c "CREATE USER admindbuser WITH PASSWORD 'ZnuLEmu72R';"
Any help is very much appreciated. I want some help in guiding how to modify the line in shell so as to achieve the required command.
Change
PGPASSWORD=change123 psql\
-h $DB \
-p 5432 \
-d postgres \
-U root \
-c \"CREATE USER $(echo "$j" | cut -d "_" -f1)dbuser WITH PASSWORD \'$(echo $DBPASSWD|base64 --decode)\';\"
to
PGPASSWORD=change123 psql \
-h "$DB" \
-p 5432 \
-d postgres \
-U root \
-c "CREATE USER ${j%%_*}dbuser WITH PASSWORD '$(printf '%s' "$DBPASSWD" | base64 --decode)';"
I am running one shell script on my App server which will go on another machine where Postgres database is installed. It will execute query and return couple of IDs and store into variables. Please find below my shell script.
ssh root#<Remote_HOST> 'bash -s'<< EOF
projectid=`/usr/pgsql-9.4/bin/psql $DB_NAME -U $DB_USER -h $DB_HOST -t -c "select projectid from projects where project_Name='$projectName';"`
scenarioid=`/usr/pgsql-9.4/bin/psql $DB_NAME -U $DB_USER -h $DB_HOST -t -c "select scenarioid from scenarios where scenario='$scenario' and projectid='$projectid';"`
EOF
echo $projectid
If i execute Shell, i get following error :
/root/test/data.sh: line 62: /usr/pgsql-9.4/bin/psql: No such file or directory
/root/test/data.sh: line 62: /usr/pgsql-9.4/bin/psql: No such file or directory
But on machine where database is installed, if i execute same query, i get proper results. So i am not sure what is wrong, query is fine and directory is present. Even after SSH to remote host, if i do ls or pwd, i am getting proper output. I have already exported database password, so database login without password is already working fine.
Can some please tell me what am i missing here?
Finally i was able to resolve my issue by making changes in Shell
projectid=$(ssh root#<Remote_HOST> << EOF
/usr/pgsql-9.4/bin/psql $DB_NAME -U $DB_USER -h $DB_HOST -t -c "select projectid from projects where project_Name='$projectName';"
EOF)
scenarioid=$(ssh root#<Remote_HOST> << EOF
/usr/pgsql-9.4/bin/psql $DB_NAME -U $DB_USER -h $DB_HOST -t -c "select scenarioid from scenarios where scenario='$scenario' and projectid='$projectid';"
EOF)
echo "$projectid : $scenarioid"
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.
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
'"
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