2013-08-14 27 views
19

Tôi có một bảng trong cơ sở dữ liệu PostgreSQL có 3 cột - c_uid, c_defaultsc_settings. c_uid chỉ lưu trữ tên người dùng và c_defaults là một đoạn văn bản dài chứa rất nhiều dữ liệu mà người dùng đó sử dụng.PostgreSQL - truy vấn từ tập lệnh bash dưới dạng người dùng cơ sở dữ liệu 'postgres'

Tôi phải thực hiện câu lệnh từ tập lệnh bash chọn giá trị của cột c_defaults dựa trên giá trị c_uid và điều này cần được thực hiện bởi người dùng cơ sở dữ liệu 'postgres'.

Trên CLI Chắc chắn bạn có thể làm như sau:

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

Tuy nhiên, làm thế nào để đạt được điều này thông qua một kịch bản bash?

Mục đích là lấy thông tin từ cột đó, chỉnh sửa và viết lại vào cột đó - tất cả thông qua tập lệnh bash.

Trả lời

55

Hãy thử điều này một:

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

Hoặc sử dụng su:

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

Và cũng sudo:

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

Tôi đã sử dụng tùy chọn thứ hai mà bạn đã cung cấp và chuyển nó thành một biến. Cảm ơn bạn. – rahuL

+0

vì vậy nó - psql và không --psql? – radtek

+1

@radtek Với khoảng cách giữa. Bạn đang gọi 'psql' với' sudo' và '--' chỉ là một dấu tách tùy chọn. – konsolebox

7

Khi bạn đã đăng nhập như postgres, bạn sẽ có thể viết:

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

để in ra chỉ là giá trị của trường đó, có nghĩa là bạn có thể chụp nó (ví dụ) tiết kiệm trong biến Bash:

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

Để xử lý đăng nhập là postgres, tôi khuyên bạn nên sử dụng sudo. Bạn có thể cấp cho một người dùng cụ thể quyền chạy

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

để họ có thể chạy chỉ một tập lệnh là postgres.

+0

'-bash-4.1 $ psql -t -d database_name $ 'SELECT c_defaults TỪ user_info WHERE c_uid = \' testuser \ ';' 'cho tôi và lỗi - _" psql: FATAL: role "SELECT c_defaults FROM user_info WHERE c_uid = 'testuser';" không tồn tại_ " – rahuL

+0

@ i.h4d35: Rất tiếc, tôi đã bỏ qua cờ' -c' (giới thiệu truy vấn hoặc lệnh cho 'psql' để chạy). Tôi đã thêm nó ngay bây giờ. – ruakh

+0

Chìa khóa cho giải pháp cho tôi là thoát khỏi những dấu nháy đơn đơn giản. Chúc mừng. –

7

nếu bạn đang có kế hoạch để chạy nó từ một tập tin sql riêng biệt. đây là một ví dụ điển hình (lấy từ một trang tuyệt vời để học làm thế nào để bash với 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 
7

Bạn có thể kết nối với các psql như dưới đây và viết các truy vấn sql của bạn như bạn làm trong một postgres chức năng thường xuyên trong khối. ở đó, các biến bash thể được sử dụng Tuy nhiên, kịch bản nên nghiêm sql, ngay cả đối với ý kiến ​​bạn cần sử dụng - thay vì #:.

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

cách an toàn nhất để vượt qua các lệnh để psql trong một kịch bản là do đường ống hoặc chuyển một tài liệu ở đây.

Tài liệu dành cho người dùng cho tùy chọn -c/--command sẽ đi vào chi tiết hơn khi cần tránh.

-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 
Các vấn đề liên quan