'Virtuelle Datei' aus der Ausgabe des Bash-Befehls erstellen?


36

Ich frage mich, ob es eine Möglichkeit gibt, eine "virtuelle Datei" aus einer Bash-Ausgabe zu erstellen.

Beispiel: Angenommen, ich möchte die Ausgabe von mysqldumpals Anhang an eine externe E-Mail-Adresse senden. Ich kann Mutt dazu benutzen. Die muttOption, die ich verwenden muss, ist -a <name of the file I want to attach>. Ich weiß, dass ich eine temporäre Datei verwenden könnte:

mysqldump mysqldumpoptions > /tmp/tempfile && mutt -a /tmp/tempfile admin@example.org

Aber ich würde die mysqldumpAusgabe lieber direkt zu Mutt umleiten . Die -aOption von Mutt akzeptiert nur eine Datei und keinen Stream, aber vielleicht gibt es eine Möglichkeit, eine Art virtuellen Dateideskriptor oder etwas Ähnliches zu übergeben. So etwas wie:

mutt -a $(mysqldump mysqldumpoptions) admin@example.org

Ist es möglich? Wenn nein, warum?

Dies ist vielleicht ein albernes Beispiel und es gibt sicherlich einfachere Möglichkeiten, dies zu tun, aber ich hoffe, es erklärt meine Frage zum Erstellen einer virtuellen Datei aus der Ausgabe eines anderen Befehls.


1
Ich konnte <() nicht zur Arbeit bringen, bis mir klar wurde, dass ich sh anstelle von bash verwendete. Es funktioniert großartig. Ich werde die hilfreichen Antworten positiv bewerten, wenn (wenn) ich den minimal benötigten Ruf erreiche. Vielen Dank für alle Antworten.
Pierre

Antworten:


53

Dies ist der sauberste Weg, um das zu tun, was Sie wollen:

mutt admin@example.org -a <(mysqldump mysqldumpoptions)

Der <()Operator ist das, wonach Sie gefragt haben. Es erstellt ein FIFO (oder / dev / fd), gibt einen Prozess aus und verbindet stdout mit dem FIFO. >()tut dasselbe, außer dass stattdessen stdin mit dem FIFO verbunden wird. Mit anderen Worten, es erledigt alles für Sie hinter den Kulissen. oder auf einem modernen Betriebssystem noch besser.

Außer natürlich, dass das mit Mutt nicht funktioniert, heißt es:

/dev/fd/63: unable to attach file.

Ich vermute, das Problem ist, dass Mutt versucht, in der Datei zu suchen, was Sie mit keiner Pipe tun können. Das Suchen ist wahrscheinlich so etwas wie das Scannen der Datei, um herauszufinden, welcher MIME-Typ es ist und welche Codierungen funktionieren könnten (dh ob die Datei 7-Bit oder 8-Bit ist), und dann das Suchen zum Anfang der Datei, um sie tatsächlich in die Nachricht zu codieren .

Wenn es sich bei dem, was Sie senden möchten, um einfachen Text handelt, können Sie immer so etwas tun, um es zum Hauptinhalt der E-Mail zu machen (nicht ideal, aber es funktioniert tatsächlich):

mysqldump mysqldumpoptions | mutt -s "Here's that mysqldump" admin@example.org

2
Genial! Ich sehe eine solche Umleitung zum ersten Mal.
Saurabh Barjatiya

Danke für die gute Erklärung! Ich habe dies noch nie zuvor in Tutorials zur E / A-Umleitung gesehen.
Christian Mann

4

Ich denke, was Sie suchen, ist eine Fifo-Verwendung mknod

mknod /tmp/foo p

echo hello > /tmp/foo &

cat /tmp/foo

Beachten Sie, dass der Schreibvorgang blockiert wird, wenn kein Lesevorgang stattfindet.

z.B

mknod /tmp/foo p

mysqldump mysqldumpoptions > /tmp/foo &

mutt -a /tmp/foo

1

Muss es ein Anhang sein? Wenn es als Hauptteil einer Nachricht angezeigt werden kann (7-Bit-Clean-ASCII, enthält kein '.' In einer eigenen Zeile usw.), funktioniert Folgendes:

mysqldump mysqldumpoptions | mutt -s "heutiger mysql dump" admin@example.org


1

Möglicherweise können Sie den Dateinamen /dev/stdinmit mutt verwenden, der aus dem Standard- Dateinamen liest.

mysqldump mysqldumpoptions | mutt -a /dev/stdin admin@example.org

Hm, ich habe es gerade ausprobiert und Mutt beschwert sich:

/dev/stdin isn't a regular file.
/dev/stdin: unable to attach file.

Naja. Ich denke, dies beantwortet Ihre Frage, mit der -aOption mutt erwartet eine reguläre Datei, die kein Gerät oder eine Pipe impliziert.


1

Ein FIFO ist wahrscheinlich der beste Weg. Sie können jedoch mkfifo /path/to/fifostattdessen verwenden


0

Ich vermisse hier vielleicht etwas, aber warum sollte ich mutt verwenden, wenn dies eher nach einem Job für / usr / sbin / sendmail klingt (oder wo immer es in Ihrer Distribution lebt)?

mysqldump mysqldumpoptions | sendmail admin@example.org

Die meisten Unix-MTAs stellen den Befehl / usr / sbin / sendmail zur Verfügung, und alle verstehen mehr oder weniger die gleichen Optionen und arbeiten mehr oder weniger auf die gleiche Weise. In fast allen Fällen müssen Sie sich nicht darum kümmern, welchen MTA / welche Implementierung von sendmail Sie verwenden.

Es gibt auch mehrere andere Alternativen, einschließlich mail / mailx


1
dann ist es kein anhang, der für den empfänger wahrscheinlich schwerer zu gebrauchen ist
freiheit

1
In diesem Fall ist es besser, ein Tool wie metamail (1) oder mime-construct (1p) zu verwenden oder ein eigenes mit dem Perl-Modul MIME :: Lite zu schreiben (mein persönlicher Favorit, weil es die Arbeit erleichtert) die häufigsten mimebezogenen Dinge).
cas

0

Die Option Mutt -a verwendet speziell MIME-Typen, die unter /etc/mime.types definiert sind. Keiner der virtuellen Dateitypen, von denen Sie denken, dass er tatsächlich ein gültiger MIME-Typ ist, ist registriert. Ich glaube also nicht, dass MUTT-Anhänge funktionieren würden. Nur zum Beweis des Konzepts können Sie versuchen, das MIME-Support-Paket zu installieren (das MIME-Dateizugriffs-Binärdateien wie "see", "edit" usw. enthält) und "see" für eine virtuelle Datei (z. B. eine Pipe) auszuführen. Sie werden sehen, dass dies der Fall ist nicht erkennen. Das grundlegende Problem ist, dass normalerweise eine virtuelle Datei den Dateninhalt im Speicher und nicht auf der Festplatte enthält. Das Dateiobjekt ist lediglich ein Zeiger. Sie können sogar versuchen, eine virtuelle Datei mit tar / gz zu verpacken und mutt glücklich zu machen, aber ich bezweifle, dass Sie am anderen Ende irgendetwas Nützliches herausholen werden ... :)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.