Hi liste, ich suche eine Lösung für folgendes kleines Problem. Eine md5summe soll an ein File angehängt werden, geht ganz einfach:
echo "hallo welt" >file md5sum file >>file
Für die konkrete Anwendung wäre nun praktisch
echo "hallo welt" | md5sum >file
Leider ist md5sum eine Senke. Ich habe nun mit tee experimentiert, um einem zweiten Kanal zu haben aber leider ohne Erfolg. Die spannende Frage lautet also, wie kann ich das durch geschickte redirekts hin bekommen ?
re, wh
Hallo,
On Wed, May 31, 2017 at 05:42:24PM +0200, walter harms wrote:
Hi liste, ich suche eine Lösung für folgendes kleines Problem. Eine md5summe soll an ein File angehängt werden, geht ganz einfach:
echo "hallo welt" >file md5sum file >>file
Für die konkrete Anwendung wäre nun praktisch
echo "hallo welt" | md5sum >file
folgendes funktioniert:
$ mkfifo md5fifo $ { (echo "hallo welt" | tee md5fifo) & md5sum < md5fifo; } > file $ rm md5fifo $ cat file hallo welt 9c261301b950b563cacc0e2312bcb447 -
Aber im Vergleich zu:
$ echo "hallo welt" > tmpfile $ { cat tmpfile; md5sum < tmpfile; } > file $ rm tmpfile $ cat file hallo welt 9c261301b950b563cacc0e2312bcb447 -
erscheint mir das zu komplex, als dass es den Aufwand wert wäre. Was stört dich denn an der einfachen Variante mit einem tmpfile?
Oder folgendes geht auch:
$ echo "hallo welt" | perl -e 'open(my $fh, "| md5sum"); while (<>) { print; print $fh $_ }' > file hallo welt 9c261301b950b563cacc0e2312bcb447 -
was mein Favorit wäre, vorausgesetzt die Maschine hat ein Perl. Vermutlich kann jemand, der sich mit Perl auskennt, das auch noch hübscher und ohne das externe md5sum machen.
Liebe Grüße Uwe
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Wed, May 31, 2017 at 05:42:24PM +0200, walter harms wrote:
Hi liste, ich suche eine Lösung für folgendes kleines Problem. Eine md5summe soll an ein File angehängt werden, geht ganz einfach:
echo "hallo welt" >file md5sum file >>file
Für die konkrete Anwendung wäre nun praktisch
echo "hallo welt" | md5sum >file
Leider ist md5sum eine Senke. Ich habe nun mit tee experimentiert, um einem zweiten Kanal zu haben aber leider ohne Erfolg. Die spannende Frage lautet also, wie kann ich das durch geschickte redirekts hin bekommen ?
Wenn Du bereit bist, Deine Seele der Bash zu verkaufen gibt es die unheimlich praktischen ">(command)" (und die Schwester "<(command)", die sich wie eine Redirection verhalten, aber "command" starten und das "redirected" Zeug da reinfüttern oder von da rausholen. Zusammen mit tee sieht das etwa so aus:
tomas@rasputin:~$ echo -ne "bim\nbam\nbum\n" | tee >(md5sum) | cat -n 1 bim 2 bam 3 bum 4 3e9dd2457bfa57c837a27260117774ab -
(Das "cat -n" am Ende der Pipeline ist nur zu Illustrationszwecken da, um zu zeigen, wie das kombinierte stdout von tee und md5sum am Schluss wieder zusammenkommen).
Die "einfache Eleganz" birgt natürlich ein finsteres Geheimnis: das da oben funktioniert nur, weil md5sum den ganzen stdin (bis zum EOF) verwursten muss, bevor es "piep" sagen kann. Wenn stattdessen im >(...) ein Filter sitzt, der schon mittendrin "quasselt", dann darfst Du etwas bunteren Output erwarten.
Hinter den Kulissen macht die Bash natürlich genau das, was Uwe mit den named pipes vorführt (die man page murmelt etwas davon, dass die >(...) und <(...) nur auf Systemen zu haben sind, die named pipes unterstützen).
Eine andere praktische Anwendung dieses Konstrukts: wer hat nicht schon zwei Verzeichnisse (nur die Dateinamenlisten) vergleichen müssen. Mit ls dir1 | sort > /tmp/d1, usw. usf. Hier als Einzeiler:
tomas@rasputin:~$ mkdir d1 tomas@rasputin:~$ for f in bim bam bum ; do touch d1/$f ; done tomas@rasputin:~$ mkdir d2 tomas@rasputin:~$ for f in bim bam bem bum ; do touch d2/$f ; done tomas@rasputin:~$ diff -u <(ls d1 | sort) <(ls d2 | sort) --- /dev/fd/63 2017-06-19 11:38:12.878923638 +0200 +++ /dev/fd/62 2017-06-19 11:38:12.878923638 +0200 @@ -1,3 +1,4 @@ bam +bem bim bum
Enjoy - -- t
Am 19.06.2017 11:39, schrieb tomas@tuxteam.de:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Wed, May 31, 2017 at 05:42:24PM +0200, walter harms wrote:
Hi liste, ich suche eine Lösung für folgendes kleines Problem. Eine md5summe soll an ein File angehängt werden, geht ganz einfach:
echo "hallo welt" >file md5sum file >>file
Für die konkrete Anwendung wäre nun praktisch
echo "hallo welt" | md5sum >file
Leider ist md5sum eine Senke. Ich habe nun mit tee experimentiert, um einem zweiten Kanal zu haben aber leider ohne Erfolg. Die spannende Frage lautet also, wie kann ich das durch geschickte redirekts hin bekommen ?
Wenn Du bereit bist, Deine Seele der Bash zu verkaufen gibt es die unheimlich praktischen ">(command)" (und die Schwester "<(command)", die sich wie eine Redirection verhalten, aber "command" starten und das "redirected" Zeug da reinfüttern oder von da rausholen. Zusammen mit tee sieht das etwa so aus:
tomas@rasputin:~$ echo -ne "bim\nbam\nbum\n" | tee >(md5sum) | cat -n 1 bim 2 bam 3 bum 4 3e9dd2457bfa57c837a27260117774ab -
(Das "cat -n" am Ende der Pipeline ist nur zu Illustrationszwecken da, um zu zeigen, wie das kombinierte stdout von tee und md5sum am Schluss wieder zusammenkommen).
Die "einfache Eleganz" birgt natürlich ein finsteres Geheimnis: das da oben funktioniert nur, weil md5sum den ganzen stdin (bis zum EOF) verwursten muss, bevor es "piep" sagen kann. Wenn stattdessen im >(...) ein Filter sitzt, der schon mittendrin "quasselt", dann darfst Du etwas bunteren Output erwarten.
Hinter den Kulissen macht die Bash natürlich genau das, was Uwe mit den named pipes vorführt (die man page murmelt etwas davon, dass die >(...) und <(...) nur auf Systemen zu haben sind, die named pipes unterstützen).
Danke für die hinweise, das mit dem <() klappt, ich habe hier tatsächlich eine Anwendung bei der es Sinn macht kein Hilfsfile zu generieren, bei meinen eigenen Versuchen hatte Probleme mit dem FIFO das die Daten am Anfang kamen, das lag aber eventuell auch daran, dass ich viel mit stdout/stderr gespielt habe.
re, wh
Eine andere praktische Anwendung dieses Konstrukts: wer hat nicht schon zwei Verzeichnisse (nur die Dateinamenlisten) vergleichen müssen. Mit ls dir1 | sort > /tmp/d1, usw. usf. Hier als Einzeiler:
tomas@rasputin:~$ mkdir d1 tomas@rasputin:~$ for f in bim bam bum ; do touch d1/$f ; done tomas@rasputin:~$ mkdir d2 tomas@rasputin:~$ for f in bim bam bem bum ; do touch d2/$f ; done tomas@rasputin:~$ diff -u <(ls d1 | sort) <(ls d2 | sort) --- /dev/fd/63 2017-06-19 11:38:12.878923638 +0200 +++ /dev/fd/62 2017-06-19 11:38:12.878923638 +0200 @@ -1,3 +1,4 @@ bam +bem bim bum
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Mon, Jun 19, 2017 at 05:37:14PM +0200, walter harms wrote:
[...]
Danke für die hinweise, das mit dem <() klappt,
Das <(...) ist schick, ne?
:-)
lg - -- t