PostgreSQL - 从bash脚本查询为数据库用户'postgres'

时间:2013-08-14 05:12:32

标签: sql bash postgresql

我的PostgreSQL数据库中有一个表,有3列 - c_uidc_defaultsc_settingsc_uid只存储用户的名称,c_defaults是一段很长的文本,其中包含许多用户的数据。

我必须从bash脚本执行一个语句,该脚本根据c_defaults值选择c_uid列的值,这需要由数据库用户'postgres'完成。

在CLI上,我可以执行以下操作:

[mymachine]# su postgres
bash-4.1$psql
postgres=#\c database_name
You are now connected to database "database_name" as user "postgres".
database_name=#SELECT c_defaults  FROM user_info WHERE c_uid = 'testuser';

但是,我如何通过bash脚本实现这一目标?

目的是从该列获取信息,编辑它并将其写回该列 - 所有这些都通过bash脚本完成。

8 个答案:

答案 0 :(得分:83)

试试这个:

#!/bin/bash
psql -U postgres -d database_name -c "SELECT c_defaults  FROM user_info WHERE c_uid = 'testuser'"

或使用su

#!/bin/bash
su -c "psql -d database_name -c \"SELECT c_defaults  FROM user_info WHERE c_uid = 'testuser'\"" postgres

还有sudo

#!/bin/bash
sudo -u postgres -H -- psql -d database_name -c "SELECT c_defaults  FROM user_info WHERE c_uid = 'testuser'"

答案 1 :(得分:17)

你可以像下面那样连接到psql并像在块中的常规postgres函数中一样编写sql查询。在那里,可以使用bash变量。但是,脚本应该是严格的sql,即使是你需要使用的注释 - 而不是#:

#!/bin/bash
psql postgresql://<user>:<password>@<host>/<db> << EOF
       <your sql queries go here>
EOF

答案 2 :(得分:12)

如果您打算从单独的sql文件运行它。这是一个很好的例子(摘自一个很棒的页面来学习如何使用postgresql进行bash http://www.manniwood.com/postgresql_and_bash_stuff/index.html

#!/bin/bash
set -e
set -u
if [ $# != 2 ]; then
   echo "please enter a db host and a table suffix"
   exit 1
fi

export DBHOST=$1
export TSUFF=$2
psql \
  -X \
  -U user \
  -h $DBHOST \
  -f /path/to/sql/file.sql \
  --echo-all \
  --set AUTOCOMMIT=off \
  --set ON_ERROR_STOP=on \
  --set TSUFF=$TSUFF \
  --set QTSTUFF=\'$TSUFF\' \
   mydatabase

   psql_exit_status = $?

   if [ $psql_exit_status != 0 ]; then
     echo "psql failed while trying to run this sql script" 1>&2
     exit $psql_exit_status
   fi

   echo "sql script successful"
exit 0

答案 3 :(得分:7)

postgres身份登录后,您应该能够写下:

psql -t -d database_name -c $'SELECT c_defaults FROM user_info WHERE c_uid = \'testuser\';'

只打印出该字段的值,这意味着您可以捕获它(例如)保存在Bash变量中:

testuser_defaults="$(psql -t -d database_name -c $'SELECT c_defaults FROM user_info WHERE c_uid = \'testuser\';')"

要以postgres方式登录,建议您使用sudo。您可以授予特定用户运行权限

sudo -u postgres /path/to/this/script.sh

这样他们就可以只运行一个脚本postgres

答案 4 :(得分:2)

在脚本中将命令传递给psql的最安全方法是通过管道传输字符串或传递here-doc。

-c/--command选项的man doc会在应该避免的时候详细说明。

   -c command
   --command=command
       Specifies that psql is to execute one command string, command, and then exit. This is useful in shell scripts. Start-up files (psqlrc and ~/.psqlrc)
       are ignored with this option.

       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 achieve that, you could pipe the string into psql, for
       example: echo '\x \\ SELECT * FROM foo;' | psql. (\\ is the separator meta-command.)

       If the command string contains multiple SQL commands, they are processed in a single transaction, unless there are explicit BEGIN/COMMIT commands
       included in the string to divide it into multiple transactions. This is different from the behavior when the same string is fed to psql's standard
       input. Also, only the result of the last SQL command is returned.

       Because of these legacy behaviors, putting more than one command in the -c string often has unexpected results. It's better to feed multiple
       commands to psql's standard input, either using echo as illustrated above, or via a shell here-document, for example:

           psql <<EOF
           \x
           SELECT * FROM foo;
           EOF

答案 5 :(得分:1)

#!/bin/bash
password='complex=!password'
PGPASSWORD=$(echo $password) psql -h example.com -U example_user -d example_db -t -c "select * from example_table1" -o example_out.txt 

答案 6 :(得分:1)

就我而言,包括身份验证要求的最佳解决方案是:

username="admin"
new_password="helloworld"

PGPASSWORD=DB_PASSWORD \
  psql -h HOSTNAME -U DB_USERNAME -d DATABASE_NAME -c \
  "UPDATE user SET password = '$new_password' WHERE username = '$username'"

此命令将更新用户密码,例如恢复情况。

信息:这里的权衡是您需要记住密码将在bash历史记录中可见。有关更多信息,请参见here

更新:我正在docker容器中运行数据库,在那里我只需要以下命令:docker exec -i container_name psql -U postgres -d postgres -c "$SQL_COMMAND"

答案 7 :(得分:0)

为了回答@Jason的问题,在我的bash脚本中,我已经将这样的球罩了(出于我的目的):

dbPass='xxxxxxxx'
.....
## Connect to the DB
PGPASSWORD=${dbPass} psql -h ${dbHost} -U ${myUsr} -d ${myRdb} -P pager=on --set AUTOCOMMIT=off

另一种方法是:

psql --set AUTOCOMMIT=off --set ON_ERROR_STOP=on -P pager=on \
     postgresql://${myUsr}:${dbPass}@${dbHost}/${myRdb}

但是您必须非常小心密码:我无法使用'和/或:来设置密码,以这种方式工作。所以最终放弃了。

-S