utworzyć „plik wirtualny” z danych wyjściowych polecenia bash?

36

Zastanawiam się, czy istnieje sposób na utworzenie „pliku wirtualnego” z wyjścia bash.

Przykład: powiedzmy, że chcę wysłać wynik mysqldumpjako załącznik do zewnętrznego adresu e-mail. Mogę do tego użyć Mutt. muttOpcja muszę używać jest -a <name of the file I want to attach>. Wiem, że mógłbym użyć pliku tymczasowego:

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

Ale wolałbym zamiast tego przekierować mysqldumpwyjście bezpośrednio do Mutt. -aOpcja Mutt'a akceptuje tylko plik, a nie strumień, ale być może istnieje sposób, aby przekazać mu jakiś wirtualny deskryptor pliku lub coś w tym stylu. Coś jak:

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

Czy to możliwe? Jeśli nie to dlaczego?

Jest to może głupi przykład i są na pewno łatwiejsze sposoby na zrobienie tego, ale mam nadzieję, że to wyjaśnia moje pytanie dotyczące tworzenia pliku wirtualnego z danych wyjściowych innego polecenia.

Pierre
źródło
1
Nie mogłem zmusić <() do pracy, dopóki nie zorientowałem się, że używam sh zamiast bash. Działa świetnie. Będę głosować pomocne odpowiedzi, gdy (jeśli) osiągnę minimalną potrzebną reputację. Dziękuję za wszystkie odpowiedzi.
Pierre

Odpowiedzi:

53

To najczystszy sposób na robienie tego, co chcesz:

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

<()Operator jest to, co zostało z prośbą o; tworzy FIFO (lub / dev / fd) i forksuje proces i łączy stdout z FIFO. >()robi to samo, tyle że zamiast tego łączy stdin z FIFO. Innymi słowy, robi to wszystko za mknod za kulisami; lub w nowoczesnym systemie operacyjnym robi to w jeszcze lepszy sposób.

Z wyjątkiem, oczywiście, że to nie działa z muttem, mówi:

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

Podejrzewam, że problem polega na tym, że mutt próbuje szukać w pliku, czego nie można zrobić na żadnym potoku. Wyszukiwanie prawdopodobnie przypomina skanowanie pliku, aby dowiedzieć się, jaki jest typ MIME i jakie kodowanie może działać (tj. Czy plik jest 7-bitowy czy 8-bitowy), a następnie wyszukiwanie do początku pliku w celu zakodowania go w wiadomości .

Jeśli to, co chcesz wysłać, to zwykły tekst, zawsze możesz zrobić coś takiego, aby zamiast tego była główną treścią wiadomości e-mail (nie jest idealna, ale w rzeczywistości działa):

mysqldump mysqldumpoptions | mutt -s "Here's that mysqldump" admin@example.org
freiheit
źródło
2
Niesamowite! Po raz pierwszy widzę takie przekierowanie.
Saurabh Barjatiya
Dziękuję za dobre wyjaśnienie! Nigdy wcześniej tego nie widziałem, w żadnym tutorialu na temat przekierowania I / O.
Christian Mann
4

Myślę, że to, czego szukasz, to użycie fifo mknod

mknod /tmp/foo p

echo hello > /tmp/foo &

cat /tmp/foo

Uwaga: proces pisania zostanie zablokowany, jeśli nie będzie procesu odczytu.

na przykład

mknod /tmp/foo p

mysqldump mysqldumpoptions > /tmp/foo &

mutt -a /tmp/foo
James
źródło
1

Czy to musi być załącznik? Jeśli może pojawić się jako treść wiadomości (7-bitowe czyste ascii, nie zawiera „.” W wierszu, itp.), To coś takiego działałoby:

mysqldump mysqldumpoptions | mutt -s „dzisiejszy zrzut MySQL” [email protected]

pgs
źródło
1

Możesz być w stanie użyć nazwy pliku /dev/stdinz mutt, który będzie czytał ze swojego standardowego wejścia.

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

Hm, właśnie próbowałem tego i mutt narzeka:

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

No cóż. Myślę, że to odpowiada na twoje pytanie, z -aopcją mutt oczekuje zwykłego pliku, który nie oznacza urządzenia ani potoku.

Greg Hewgill
źródło
1

FIFO jest prawdopodobnie najlepszym sposobem. Możesz jednak użyć mkfifo /path/to/fifozamiast tego

Rory
źródło
0

może coś tu brakuje, ale po co używać mutt, jeśli brzmi to bardziej jak praca dla / usr / sbin / sendmail (lub gdziekolwiek mieszka na twojej dystrybucji)?

mysqldump mysqldumpoptions | sendmail [email protected]

większość uniksowych MTA zawiera polecenie / usr / sbin / sendmail i wszystkie one rozumieją mniej więcej te same opcje i działają mniej więcej w ten sam sposób. w prawie wszystkich przypadkach nie musisz dbać o to, którego konkretnego MTA / implementacji sendmaila używasz.

istnieje również kilka innych alternatyw, w tym mail / mailx

cas
źródło
1
to nie jest załącznik, który wydaje się być trudniejszy w użyciu dla odbiorcy
freiheit
1
w takim przypadku lepszym rozwiązaniem byłoby użycie narzędzia takiego jak metamail (1) lub mime-construct (1p) lub napisanie własnego przy użyciu czegoś takiego jak moduł perl MIME :: Lite (mój osobisty ulubiony, ponieważ ułatwia to wykonanie najczęstsze rzeczy związane z mimem).
cas
0

Opcja Mutt -a konkretnie używa typów MIME zdefiniowanych w /etc/mime.types. Żaden wirtualny typ pliku, który Twoim zdaniem nie jest prawidłowym typem MIME, nie jest zarejestrowany, więc nie sądzę, aby załącznik mutt działał. Tylko dla potwierdzenia tej koncepcji możesz spróbować zainstalować pakiet obsługi mime (który zapewnia pliki binarne dostępu do plików mime, takie jak zobacz, edytuj itp.) I uruchomić zobacz przeciwko plikowi wirtualnemu (powiedzmy potoku), zobaczysz, że to robi nie rozpoznać tego. Podstawową kwestią jest to, że zwykle plik wirtualny przechowuje dane w pamięci, a nie na dysku, obiekt pliku jest tylko wskaźnikiem. Możesz nawet spróbować owinąć wirtualny plik za pomocą tar / gz i uszczęśliwić mutta, ale wątpię, czy uzyskasz coś przydatnego z drugiego końca ... :)


źródło