Mehrmaliges Ausführen des gleichen Befehls mit mehreren Argumenten nach einer Pipe

Mehrmaliges Ausführen des gleichen Befehls mit mehreren Argumenten nach einer Pipe

Ich habe einen Schlüssel (aus zufälligen Binärdaten), der von generiert wird get_key.

Und mit diesem Schlüssel kann ich verschiedene Dinge mit meinen verschlüsselten Dateien machen. Ich kann sie zum Beispiel entschlüsseln.

get_key | tee >(decrypt file1) >(decrypt file2)

Ich würde gerne wissen, wie ich das auf nDateien verallgemeinern kann, bei denen die Dateien als angegeben sind FILES=file1 file2 file3 file4 file5.

Im Moment sehe ich zwei Lösungen:

1) Berechnen Sie eine Zeichenfolge und evalsie

2) Ersetzen Sie „decrypt“ durch eine rekursive Funktion f, die „decrypt does“ aufruft tee >(decrypt A[0]) | f ("${A[@]:1}")(sie entschlüsselt das erste Element und ruft sich selbst rekursiv auf), wenn das Array nicht leer ist, und nichts, wenn es leer ist.

Ich wollte wissen, ob Sie eine einfachere Möglichkeit dafür haben (beachten Sie, dass ich nicht möchte, dass der Schlüssel in eine Datei oder Variable geschrieben wird, Schleifen sind also keine Option).


Edit: Ich werde es verwenden inhttps://github.com/xavierm02/combine-keys

Antwort1

In Ihrem Anwendungsfall macht es keinen Sinn, mit der Entschlüsselung zu beginnen, bevor der Schlüssel vollständig generiert ist. Sie müssen die decryptProzesse also erst starten, wenn get_keysie abgeschlossen sind. Daher hat eine Pipe keinen Vorteil. Sie können die Ausgabe auch get_keyirgendwo speichern und später verwenden.

Das Speichern der Ausgabe in einer Variablen ist der einfachste Weg. Da es sich jedoch um Binärdaten handelt, die Nullbytes enthalten können,dies funktioniert nur in zsh, nicht in anderen Shells. Wenn Sie sich Sorgen um die Sicherheit machen, können Sie beruhigt sein: Ein Angreifer, der den Inhalt der Variable beobachten kann, kann sie auch ausführen get_keyund ihre Ausgabe beobachten.

key=$(get_key)
for file in $FILES; do
  print -rn -- $key | decrypt $file
done

In anderen Shells können Sie eine temporäre Datei verwenden. Achten Sie darauf, dass diese nur für Sie lesbar ist. Wenn sich die temporäre Datei auf einem Dateisystem auf der Festplatte befindet, besteht ein geringes Risiko, dass der Schlüssel verloren geht, wenn die Festplatte des Servers zum falschen Zeitpunkt gestohlen wird. Wenn sich die Datei auf einem Dateisystem im Arbeitsspeicher befindet, besteht dieses Risiko nicht.

key_file=$(umask 077; mktemp)
get_key >"$key_file"
for file; do
  decrypt "$file" <"$key_file"
done
rm "$key_file"

Wenn Sie keine temporäre Datei verwenden möchten und kein zsh haben, können Sie eine andere Sprache wie Perl oder Python verwenden.

perl -e '
    $key = `get_key`;
    foreach (@ARGV) {
        open KEY, "|-", "decrypt", $_ or die $!;
        print KEY $key or die $!;
        close KEY or die $!;
    }'

Wenn Sie keine bessere Sprache als eine POSIX-Shell oder KSH oder Bash haben und keine temporäre Datei verwenden können, müssen Sie auf das Pipe-In zurückgreifen tee(oder eine komplizierte Kodierung und Dekodierung durchführen). Um mit der variablen Anzahl von Ausgaben zurechtzukommen, können SieErstellen Sie ein FIFO pro Ausgang, oder build und evaleine Zeichenfolge, die das Notwendige enthält <(…)(Vorsicht vor den kniffligen Anführungszeichen).

Antwort2

Erstellen Sie FIFOs in einer Schleife und lassen Sie Ihre decrypts warten, bis sie geschrieben werden:

for i in "${A[@]}";do
    mkfifo /tmp/"$i"_fifo
    decrypt "$i" </tmp/"$i"_fifo &
done
getkey | tee >/dev/null /tmp/*_fifo
rm -f /tmp/*_fifo

verwandte Informationen