Hier ist ein Skript, das eine Datei nacheinander mit zwei verschiedenen symmetrischen Chiffren symmetrisch verschlüsselt/entschlüsselt.
#!/bin/bash
if [ "$#" -ne 2 ]; then
echo "Arguments: enc|dec filename"
exit
fi
E="gpg -o - --symmetric --cipher-algo"
D="gpg -o - --decrypt"
ERR="2>/dev/null"
if [ "$1" = "enc" ]; then
$E AES $2 | $E TWOFISH -
elif [ "$1" = "dec" ]; then
$D $2 ${ERR} | $D - ${ERR}
else
echo "Arguments: enc|dec filename"
exit
fi
Beim Ausführen ./doublecrypt dec /tmp/test.encrypted
erhalte ich die Fehler
usage: gpg [options] --decrypt [filename]
usage: gpg [options] --decrypt [filename]
Wenn ich die Zeile ändere
$D $2 ${ERR} | $D - ${ERR}
Zu
echo "$D $2 ${ERR} | $D - ${ERR}"
Es druckt
gpg -o - --decrypt /tmp/xenc 2>/dev/null | gpg -o - --decrypt - 2>/dev/null
Wenn ich dies kopiere und in Bash einfüge, läuft es korrekt.
Warum funktioniert es also nicht, wenn ich es entferne echo
und es, wie in der Originalform, direkt vom Bash-Skript auswerten lasse?
Ich verwende Ubuntu Saucy und Bash ist meine Shell.
Antwort1
Kurze Antwort: sieheBashFAQ Nr. 50: Ich versuche, einen Befehl in eine Variable einzufügen, aber die komplexen Fälle schlagen immer fehl!.
Lange Antwort: Sie geraten wegen der Reihenfolge, in der die Shell verschiedene Elemente von Befehlszeilen analysiert, in Schwierigkeiten. Insbesondere erweitert sie Variablenreferenzen (wie ${ERR}
) etwa in der Mitte des Prozesses – nachdem sie bereits Dinge wie Anführungszeichen, Escapezeichen und Umleitungen behandelt hat. In Ihrem Fall ist der Umleitungsteil wichtig: Bis die Shell ${ERR}
in erweitert 2>/dev/null
, hat sie bereits nach Umleitungen gesucht und keine gefunden, also behandelt sie es einfach 2>/dev/null
als Argument für den Befehl und gpg
lehnt es dann als sinnlos ab.
Grundsätzlich ist das Speichern von Befehlen (oder Befehlselementen) in Variablen der falsche Weg. Variablen sind für Daten gedacht, nicht für ausführbaren Code. In diesem Fall wäre es viel besser, stattdessen Funktionen zu verwenden:
e() {
gpg -o - --symmetric --cipher-algo "$@"
}
d() {
gpg -o - --decrypt "$@" 2>/dev/null
}
if [ "$1" = "enc" ]; then
e AES "$2" | e TWOFISH -
elif [ "$1" = "dec" ]; then
d "$2" | d -
else
echo "Arguments: enc|dec filename"
exit
fi
Beachten Sie, dass ich es auch $2
in Anführungszeichen gesetzt habe, um zu verhindern, dass der Wert der zweiten Hälfte des Shell-Analyseprozesses unterzogen wird.
Antwort2
Versuchen Sie es mit einer Änderung $D $2 ${ERR} | $D - ${ERR}
zu:
$( $D $2 ${ERR} | $D - ${ERR} )
Verwenden Sie außerdem den vollständigen Pfad zu Ihrem gpg
Programm, zB:
/usr/local/bin/gpg