bash script inhalt von datei pipen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
r4pt0r
Beiträge: 1237
Registriert: 30.04.2007 13:32:44
Lizenz eigener Beiträge: MIT Lizenz

bash script inhalt von datei pipen

Beitrag von r4pt0r » 20.01.2015 17:47:29

Ich versuche den Inhalt einer csv-datei (pfad in einer Variablen) per pipe an psql zu leiten - bash wertet aber entweder den inhalt der csv aus oder piped den Dateipfad.

codeschnipsel (ohne verbindungsparameter für psql):

Code: Alles auswählen

cat $datei | psql -c "COPY $tabellenname FROM STDIN WITH CSV DELIMITER ';'"
Ich habe mittlerweile zig Varianten von < oder | umleitungen, $(cat $datei), echo "$(cat $datei)" und sonstige Verrenkungen probiert - sobald "cat" ausgeführt wird wertet bash dessen Ausgabe aus anstatt es einfach weiter zu schicken....

Diverse Suchen brahchten mich auch nicht weiter - "Empfohlen" wird ständig Dateien Zeilenweise zu lesen und zu pipen - was bei >250t Zeilen absolut nicht Praktikabel ist da dann für jede Zeile wieder eine Verbindung zum PSQL-Server aufgebaut wird anstatt einfach alles auf einmal abzuladen...

newdeb
Beiträge: 134
Registriert: 03.02.2011 11:11:21
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Frankfurt

Re: bash script inhalt von datei pipen

Beitrag von newdeb » 20.01.2015 19:10:42

Die genaue Bash- (oder sonstige) Konsolenausgabe wäre hilfreich.
Ich würde vorsichtshalber die Pfad-Variable quotieren:

Code: Alles auswählen

cat "$datei" | ...

Benutzeravatar
Meillo
Moderator
Beiträge: 9235
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash script inhalt von datei pipen

Beitrag von Meillo » 21.01.2015 08:07:27

r4pt0r hat geschrieben:Ich versuche den Inhalt einer csv-datei (pfad in einer Variablen) per pipe an psql zu leiten - bash wertet aber entweder den inhalt der csv aus oder piped den Dateipfad.

codeschnipsel (ohne verbindungsparameter für psql):

Code: Alles auswählen

cat $datei | psql -c "COPY $tabellenname FROM STDIN WITH CSV DELIMITER ';'"
Was funktioniert denn an dem von dir bereits gelieferten Codeschnipsel nicht?
Use ed once in a while!

r4pt0r
Beiträge: 1237
Registriert: 30.04.2007 13:32:44
Lizenz eigener Beiträge: MIT Lizenz

Re: bash script inhalt von datei pipen

Beitrag von r4pt0r » 21.01.2015 08:18:04

Ausgabe bei Aufruf der cat | psql Pipe per Script:

Code: Alles auswählen

.....
FEHLER:  Syntaxfehler bei »34«
ZEILE 1: 34;
         ^
FEHLER:  Syntaxfehler bei »34«
ZEILE 1: 34;
         ^
FEHLER:  Syntaxfehler bei »34«
ZEILE 1: 34
         ^
FEHLER:  Syntaxfehler bei »37«
ZEILE 1: 37;
         ^
FEHLER:  Syntaxfehler bei »37«
ZEILE 1: 37;
         ^
FEHLER:  Syntaxfehler bei »37«
ZEILE 1: 37;
         ^
FEHLER:  Syntaxfehler bei »37«
ZEILE 1: 37
         ^
FEHLER:  Syntaxfehler bei »40«
ZEILE 1: 40;
         ^
FEHLER:  Syntaxfehler bei »40«
ZEILE 1: 40;
         ^
FEHLER:  Syntaxfehler bei »40«
ZEILE 1: 40;
         ^
.....
Die selbe Zeile diekt "von Hand" in bash ausgeführt (mit Werten für die beiden Variablen) funktioniert einwandfrei. Die Variablen im Script sind korrekt definiert - in anderen Funktionen werden nach selbem Schema Datenbanktabellen angelegt und Werte ausgelesen bzw andere Dateien anderweitig verarbeitet. Es hängt hier nur an dieser Pipe (die für "copy from" benötigt wird) und dass bash bei Ausführung per Script eben NICHT piped sondern die Ausgabe von "cat" verarbeiten will...


PS: wenn es eine andere Variante gibt den inhalt einer Datei über die Standardausgabe in psql zu füttern bin ich natürlich auch glücklich...

Benutzeravatar
Meillo
Moderator
Beiträge: 9235
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash script inhalt von datei pipen

Beitrag von Meillo » 21.01.2015 09:56:58

r4pt0r hat geschrieben: Es hängt hier nur an dieser Pipe (die für "copy from" benötigt wird) und dass bash bei Ausführung per Script eben NICHT piped sondern die Ausgabe von "cat" verarbeiten will...
Ich vermute, dass das Problem in keiner Weise etwas mit der Bash zu tun hat. Denn die Bash piped sehr wohl und sie verarbeitet keine Ausgabe von cat.

Ich vermute, dass es sich hier nur um ein Problem mit psql handelt.

Mir scheint, dass psql SQL-Befehle von stdin lesen will. Normalerweise wird es wohl interaktiv verwendet und liest sie somit (via stdin) vom Terminal. Man kann es aber wohl auch automatisiert aufrufen, in der Art <befehle.sql psql oder in der Art psql -c "sql-befehl". Scheinbar kann man die zwei Arten auch kombinieren: <befehle.sql psql -c "sql-befehl". Dann scheint er sie nacheinander auszufuehren. Vielleicht liegt das Problem nur daran, dass er zuerst stdin verarbeitet und dann -c (falls dem so ist). Oder es liegt daran, dass man ``COPY ... FROM STDIN'' nur im interaktiven Modus verwenden kann.

Das jedenfalls sind die mir momentan vorstellbaren Erklaerungen.

(Ich sollte wohl noch erwaehnen, dass ich psql(1) nie verwendet habe. Ich habe nur seine Manpage ueberflogen und verwende mysql(1) ab und an.)


... vielleicht wirst du um eine temporaere Datei nicht rum kommen.
Use ed once in a while!

r4pt0r
Beiträge: 1237
Registriert: 30.04.2007 13:32:44
Lizenz eigener Beiträge: MIT Lizenz

Re: bash script inhalt von datei pipen

Beitrag von r4pt0r » 21.01.2015 10:13:20

Ich habe mittlerweile ein funktionierendes Konstrukt gefunden:

Code: Alles auswählen

( echo "COPY $tabellenname FROM STDIN WITH CSV DELIMITER ';';" 
cat $datei ) | psql
Warum bash sich darüber mehr freut als über

Code: Alles auswählen

( cat $datei | psql "COPY $tabellenname FROM STDIN WITH CSV DELIMITER ';';")
oder

Code: Alles auswählen

( cat $datei ) | psql "COPY $tabellenname FROM STDIN WITH CSV DELIMITER ';';"
ist mir noch schleierhaft... Es funktioniert jetzt aber und ich kann mich nach ca 4h Rumärgern endlich wieder dem rest des codes widmen...


Ich hoffe das hilft mal jemandem (und erspart Nerven und graue Haare :roll: ) der über ein ähnliches Problem stolpert.

Benutzeravatar
Meillo
Moderator
Beiträge: 9235
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash script inhalt von datei pipen

Beitrag von Meillo » 21.01.2015 10:35:33

r4pt0r hat geschrieben:Ich habe mittlerweile ein funktionierendes Konstrukt gefunden:

Code: Alles auswählen

( echo "COPY $tabellenname FROM STDIN WITH CSV DELIMITER ';';" 
cat $datei ) | psql
Schoen!

psql liest also nach dem Strichpunkt auf stdin einfach weiter. Nett! ;-)

Warum bash sich darüber mehr freut als über
[...]
ist mir noch schleierhaft...
Nochmal und nun deutlicher, denn ich bin mir jetzt sicher: Das Problem hat rein gar nichts mit der Bash zu tun. Das Problem betrifft alleine psql(1). Dessen Entwickler musst du fragen, warum sie es so programmiert haben.
Use ed once in a while!

r4pt0r
Beiträge: 1237
Registriert: 30.04.2007 13:32:44
Lizenz eigener Beiträge: MIT Lizenz

Re: bash script inhalt von datei pipen

Beitrag von r4pt0r » 21.01.2015 11:57:37

Meillo hat geschrieben:
r4pt0r hat geschrieben:Ich habe mittlerweile ein funktionierendes Konstrukt gefunden:

Code: Alles auswählen

( echo "COPY $tabellenname FROM STDIN WITH CSV DELIMITER ';';" 
cat $datei ) | psql
Schoen!

psql liest also nach dem Strichpunkt auf stdin einfach weiter. Nett! ;-)
Das "soll" wohl das erwünschte/normale verhalten des COPY FROM STDIN befehls sein - nach ausführen liest psql den folgenden stream und beendet dann die verbindung wenn nichts mehr kommt. Mir graust es bei (XYZ)SQL sowieso schon an allen Ecken und Enden (vor allem da ich in letzter Zeit fast nur noch C/ASM auf AVR Programmiere...) - da mach ich mir über das Konstrukt auch keinen Kopf mehr :roll:
Immerhin ist PostgeSQL nicht ganz so unglaublich Hirnrissig wie MSSQL - wobei das auch Pest vs Cholera zu sein scheint...

Antworten