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 - macos

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
'"

Related

Copy output of sql-query to a file

I want to export a random entry of my database into a file with the command
SELECT * FROM my_table ORDER BY RANDOM() LIMIT 1 \g /path/file;
This query works if I enter it in my db terminal, but I want to us this query with a bash script but then I get the error: syntax error at or near "\g"
My bash script looks like this:
PGPASSWORD=*** psql -U user -d db_name -h localhost -p port -t -c "SELECT * FROM my_table ORDER BY RANDOM() LIMIT 1 \g /path/file"
Bash is interpreting the string and trying to interpolate it. Probably, escaping the backslash will solve your problem.
PGPASSWORD=*** psql -U user -d db_name -h localhost -p port -t -c "SELECT * FROM my_table ORDER BY RANDOM() LIMIT 1 \\g /path/file"
A SQL statement terminated by \g is not supported by the -c command switch. Per documentation of -c:
-c command
...
command must be either a command string that is completely parsable by the server (i.e., it contains no psql-specific features), or a single backslash command. Thus you cannot mix SQL
and psql meta-commands with this option
To redirect the results to a file, there are several options:
shell redirection: psql [other options] -Atc 'SELECT...' >/path/to/data.txt
-A is to switch to unaligned mode (no space fillers to align columns).
put the SQL part in a heredoc text instead of the command line:
psql [options] <<EOF
SELECT ... \g /path/to/file
EOF
This form has the advantage that multiline statements or multiple statements are supported directly.
\copy of the query. Be aware that COPY to a FILE is different: it creates the file on the server with the permissions of postgres and requires being a database superuser. COPY TO STDOUT works too but is not better than SELECT concerning the redirection.
I found a solution for my script, and now it works.
#!/bin/bash
RANDOM_NUMBER=0
while true
do
for i in `seq 1`
do
RANDOM_NUMBER=$(($RANDOM % 100000))
echo $RANDOM_NUMBER
PGPASSWORD=*** psql -U user_name -d db_name -h localhost -p PORT -c
"INSERT INTO numbers (number) VALUES ('$RANDOM_NUMBER');"
done
sleep 10
for i in `seq 1`
do
PGPASSWORD=*** psql -U user_name -d db_name -h localhost -p PORT -c
"DELETE FROM numbers WHERE id = (SELECT id FROM numbers ORDER BY RANDOM() LIMIT 1);"
done
done

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;"'

Facing issue in Shell while executing query on remote postgres database

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"

how to periodically dump a set of database tables to a local machine from a psql database in a single bash script run on Mac OS X?

I tried this but it does not 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
'"
You should use the Postgres COPY command, and stuff them all in to a single sql file, that you then run with psql. Then you can take that script and either feed it to cron on Mac OS X, or launchd to run the script periodically.

insert bash-variables in psql-command

I'm going crazy while trying to insert bash-variables in a psql commands as connection paramters as well as variables in the command itself. The following example works properly:
psql -U postgres -h localhost -p 5432 -c "CREATE DATABASE testdb WITH ENCODING='UTF8' OWNER=postgres TABLESPACE=pg_default TEMPLATE=template_postgis CONNECTION LIMIT=-1;"
Now I'm trying to exchange each parameter through a variable, which is held in special config-file.
Non-working example:
dbserver=localhost
dbport=5432
dbowner=postgres
dbname=testdb
dbtemplate=template_postgis
dbtablespace=pg_default
psql -U '$dbowner' -h '$dbserver' -p '$dbport' -c "CREATE DATABASE '$dbname' WITH ENCODING='UTF8' OWNER='§dbowner' TABLESPACE='$dbtablespace' TEMPLATE='$dbtemplate'
CONNECTION LIMIT=-1;"
I've tried several quotings, backquotes and escape-slashes already but smhow it still won't work.
Thanks in advance, knutella
Use double quotes ("). Single quotes (') does not interpret shell variables inside.
Try it
echo '$USER' "$USER"
See man bash.
This works... most of the quotes are not needed:
psql -U $dbowner -h $dbserver -p $dbport -c "CREATE DATABASE $dbname WITH ENCODING='UTF8' OWNER=$dbowner TABLESPACE=$dbtablespace TEMPLATE=$dbtemplate CONNECTION LIMIT=-1;"

Resources