Подтвердить что ты не робот

PostgreSQL - запрос из bash script как пользователь базы данных postgres '

У меня есть таблица в моей базе данных PostgreSQL, которая имеет 3 столбца - c_uid, c_defaults и c_settings. c_uid просто сохраняет имя пользователя, а c_defaults - длинный фрагмент текста, который содержит много данных w.r.t этого пользователя.

Мне нужно выполнить инструкцию из bash script, которая выбирает значение столбца 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 script?

Цель состоит в том, чтобы получить информацию из этого столбца, отредактировать ее и записать обратно в этот столбец - через bash script.

4b9b3361

Ответ 1

Попробуйте следующее:

#!/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'"

Ответ 2

Вы можете подключиться к psql, как показано ниже, и написать свои SQL-запросы, как в обычной функции postgres внутри блока. Там могут использоваться переменные bash. Однако script должен быть строго sql, даже для комментариев, которые вам нужно использовать, вместо #:

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

Ответ 3

если вы планируете запустить его из отдельного файла sql. вот хороший пример (взята с большой страницы, чтобы узнать, как bash с postgresql 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

Ответ 4

Как только вы вошли в систему под 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

чтобы они могли запускать только один script как postgres.

Ответ 5

Самый безопасный способ передать команды psql в script - путем связывания строки или передачи здесь-документа.

Документы man для параметра -c/--command более подробно рассматриваются, когда его следует избегать.

   -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 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 better to feed multiple
       commands to psql standard input, either using echo as illustrated above, or via a shell here-document, for example:

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

Ответ 6

На вопрос @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