Thực thi các lệnh hệ thống trong postgresql


8

Yêu cầu của tôi là thực thi một lệnh hệ thống như (ls) hoặc chương trình C khi kích hoạt thực thi. Có cách nào để tạo một chức năng kích hoạt để giải quyết vấn đề này.


2
Bạn có thể sử dụng một ngôn ngữ không đáng tin cậy như PL / perl, điều này sẽ cho phép bạn gọi các lệnh của hệ điều hành: postgresql.org/docs/civerse/static/plperl-trust.html
a_horse_with_no_name 4/2/2016

Câu trả lời:


13

Bạn có thể dễ dàng làm những gì @a_horse_with_no_name gợi ý trong bình luận của mình. Nhưng cũng có một cách thú vị để làm điều đó, sử dụng PL / pgSQL làm ngôn ngữ hàm.

Điều này sử dụng một tính năng của COPYlệnh, được giới thiệu trong PostgreSQL 9.3. Giờ đây, nó có thể nhận lệnh làm đích / nguồn, chính xác là nơi bạn sử dụng tên tệp hoặc STDIN / STDOUT trong các trường hợp thông thường:

COPY table_name [ ( column_name [, ...] ) ]
    FROM { 'filename' | PROGRAM 'command' | STDIN }
    [ [ WITH ] ( option [, ...] ) ]

Rõ ràng, bạn cần một bảng để đặt đầu ra, nhưng bạn có thể bỏ qua nó, nếu bạn muốn.

Xem một ví dụ nhỏ:

CREATE TABLE trigger_test (
    tt_id serial PRIMARY KEY,
    command_output text
);

CREATE OR REPLACE FUNCTION trigger_test_execute_command()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $BODY$
BEGIN
    COPY trigger_test (command_output) FROM PROGRAM 'echo 123';
    RETURN NULL;
END;
$BODY$;

CREATE TABLE trigger_test_source (
    s_id integer PRIMARY KEY
);

CREATE TRIGGER tr_trigger_test_execute_command
    AFTER INSERT
    ON trigger_test_source
    FOR EACH STATEMENT
    EXECUTE PROCEDURE trigger_test_execute_command();

INSERT INTO trigger_test_source VALUES (2);

TABLE trigger_test;
 tt_id  command_output 
───────┼────────────────
     1  123

Lưu ý: chức năng cần phải chạy với quyền superuser - nghĩa là, thực hiện INSERTnhư một siêu người dùng hoặc xác định chức năng với SECURITY DEFINER. Trong mọi trường hợp khác, bạn sẽ gặp lỗi:

ERROR:  must be superuser to COPY to or from an external program
HINT:  Anyone can COPY to stdout or from stdin. psql's \copy command also works for anyone.

Lưu ý rằng TO PROGRAMphần này yêu cầu một chuỗi ký tự, vì vậy nếu bạn muốn một lệnh động, bạn phải bọc toàn bộ EXECUTE. Xem stackoverflow.com/a/42626659/5419599 .
tự đại diện

Bạn có thể vui lòng giúp tôi với câu hỏi của tôi: stackoverflow.com/questions/61071706/
ankit

6

Nếu bạn chỉ cần nhìn vào một cái gì đó liên quan đến $PGDATAbạn có thể sử dụng pg_ls_data

SELECT pg_ls_dir('pg_xlog');

Mặt khác, một chức năng đơn giản như thế này:

CREATE OR REPLACE FUNCTION ls(location text) RETURNS text AS $BODY$
    use warnings;
    use strict;
    my $location = $_[0];
    my $output = `ls -l $location`;
    return($output);
$BODY$ LANGUAGE plperlu;

Sẽ cung cấp cho bạn đầu ra như thế này:

user1@[local]:5432:user1:=# SELECT * FROM ls('/usr/local/pgsql/data');
                                       ls                                            
-----------------------------------------------------------------------------------------
 total 104                                                                              +
 -rw-------  1 pgsql  pgsql      4 Jan 14 14:33 PG_VERSION                              +
 drwx------  8 pgsql  pgsql      8 Jan 15 12:27 base                                    +
 drwx------  2 pgsql  pgsql     54 Feb  4 01:30 global                                  +
 drwx------  2 pgsql  pgsql      4 Jan 15 12:57 pg_clog                                 +
 drwx------  2 pgsql  pgsql      2 Jan 14 14:33 pg_commit_ts                            +
 drwx------  2 pgsql  pgsql      2 Jan 14 14:33 pg_dynshmem                             +
 -rw-------  1 pgsql  pgsql   4458 Feb  4 01:29 pg_hba.conf                             +
 -rw-------  1 pgsql  pgsql   1725 Jan 20 15:29 pg_ident.conf                           +
 drwx------  4 pgsql  pgsql      5 Feb  4 02:14 pg_logical                              +
 drwx------  4 pgsql  pgsql      4 Jan 14 14:33 pg_multixact                            +
 drwx------  2 pgsql  pgsql      3 Feb  4 01:29 pg_notify                               +
 drwx------  2 pgsql  pgsql      2 Jan 14 14:33 pg_replslot                             +
 drwx------  2 pgsql  pgsql      2 Jan 14 14:33 pg_serial                               +
 drwx------  2 pgsql  pgsql      2 Jan 14 14:33 pg_snapshots                            +
 drwx------  2 pgsql  pgsql      2 Feb  4 01:29 pg_stat                                 +
 drwx------  2 pgsql  pgsql      8 Feb  4 02:17 pg_stat_tmp                             +
 drwx------  2 pgsql  pgsql      3 Jan 15 13:08 pg_subtrans                             +
 drwx------  2 pgsql  pgsql      2 Jan 14 14:33 pg_tblspc                               +
 drwx------  2 pgsql  pgsql      2 Jan 14 14:33 pg_twophase                             +
 lrwxr-xr-x  1 pgsql  pgsql     29 Jan 14 14:34 pg_xlog -> /usr/local/pgsql/xlog/pg_xlog+
 -rw-------  1 pgsql  pgsql     88 Jan 14 14:33 postgresql.auto.conf                    +
 -rw-------  1 pgsql  pgsql  21821 Jan 20 15:27 postgresql.conf                         +
 -rw-------  1 pgsql  pgsql     53 Feb  4 01:29 postmaster.opts                         +
 -rw-------  1 pgsql  pgsql     79 Feb  4 01:29 postmaster.pid                          +

(1 row)

Time: 4.361 ms
user1@[local]:5432:user1:=#

1
Xin lưu ý rằng điều này cũng chỉ có thể được chạy với quyền siêu người dùng (hoặc sử dụng SECURITY DEFINER).
dezso 4/2/2016

@dezso Khá đúng. Cảm ơn bạn đã thêm điểm đó. =)
Kassandry
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.