it-swarm.com.de

Führen Sie Systembefehle in postgresql aus

Meine Anforderung besteht darin, einen Systembefehl wie (ls) oder C-Programm auszuführen, wenn ein Trigger ausgeführt wird. Gibt es eine Möglichkeit, eine Triggerfunktion zu erstellen, um dieses Problem zu lösen?.

8
mrg

Sie können leicht tun, was @ a_horse_with_no_name in seinem Kommentar vorschlägt. Es gibt aber auch eine interessante Möglichkeit, PL/pgSQL als Funktionssprache zu verwenden.

Dies verwendet eine Funktion des in PostgreSQL 9.3 eingeführten Befehls COPY . Es kann jetzt einen Befehl als Ziel/Quelle annehmen, genau dort, wo Sie im Normalfall einen Dateinamen oder STDIN/STDOUT verwenden würden:

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

Natürlich benötigen Sie eine Tabelle, um die Ausgabe zu platzieren, aber Sie können sie ignorieren, wenn Sie möchten.

Siehe ein kleines Beispiel:

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

Hinweis: Die Funktion muss mit Superuser-Rechten ausgeführt werden. Führen Sie entweder INSERT als Superuser aus oder definieren Sie die Funktion mit SECURITY DEFINER. In jedem anderen Fall erhalten Sie eine Fehlermeldung:

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.
13
dezso

Wenn Sie nur etwas relativ zu $PGDATA Sie können pg_ls_data verwenden

SELECT pg_ls_dir('pg_xlog');

Ansonsten eine einfache Funktion wie diese:

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;

Gibt Ihnen folgende Ausgabe:

[email protected][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
[email protected][local]:5432:user1:=#
5
Kassandry