Anführen von Befehlszeilenargumenten in Shell-Skripten
Beim Schreiben von Shell-Skripten, insbesondere für Anwendungen wie WINE, die mit Windows-Dateistrukturen interagieren, ist es entscheidend, Befehlszeilenargumente korrekt anzuführen. Ein häufiges Problem ist die falsche Handhabung dieser Argumente, was zu Fehlern führen kann, wenn Pfade Leerzeichen oder Sonderzeichen enthalten. In diesem Beitrag werden wir erörtern, wie man solche Anführungszeichen-Probleme effektiv handhabt und löst.
Das Problem
Betrachten wir ein Szenario, in dem Sie ein Shell-Skript haben, das eine WINE-Anwendung ausführen soll. Das Skript nimmt eine Liste von Argumenten entgegen, konvertiert Unix-Pfade in Windows-Pfade und ruft dann die ausführbare Datei auf. Leider tritt aufgrund unsachgemäßer Anführungszeichen in den Befehlszeilenargumenten ein Fehler auf:
wine: cannot find ''/home/chris/.wine/drive_c/Program'
Wichtige beobachtete Probleme:
- Path Chopping: Der Pfad zur ausführbaren Datei wird beim ersten Leerzeichen abgeschnitten, obwohl er in einfache Anführungszeichen eingeschlossen ist.
- Backslash-Interpretation: Ein Backslash gefolgt von ’t’ (
\t
) wird als Tabulatorzeichen und nicht als literale Zeichenfolge interpretiert.
Verständnis des Anführungszeichen-Problems
Diese Probleme ergeben sich aus der Art und Weise, wie die Shell Anführungszeichen und Sonderzeichen in Befehlsersetzungen interpretiert. Hier ist, warum diese Probleme auftreten:
- Wenn Argumente an die Shell übergeben werden, können Leerzeichen dazu führen, dass der Befehl auseinandergerissen wird, es sei denn, sie sind richtig angeführt.
- Variablen, die in Strings erweitert werden, können Escape-Zeichen enthalten, die ebenfalls sorgfältig behandelt werden müssen, um unerwünschte Transformationen zu vermeiden.
Wenn Sie beispielsweise eine Variable, die Escape-Sequenzen enthält, ausgeben, können diese falsch interpretiert werden. Das könnte so aussehen:
Y='y\ty'
Z="z${Y}z"
echo $Z # Gibt aus: zy yz (nicht zy yz)
Solches Verhalten kann zu Debugging-Herausforderungen und unerwarteten Ergebnissen in Skripten führen.
Die Lösung
Um diese Probleme mit Anführungszeichen zu lösen, insbesondere in unserem Shell-Skript-Beispiel, können wir den integrierten Befehl eval
verwenden. Dieser Befehl wertet die bereitgestellten Argumente neu aus, wodurch die korrekte Analyse der Befehlszeichenfolge vor der Ausführung ermöglicht wird.
Schritt-für-Schritt-Lösung
-
Ändern Sie die letzte Zeile des Skripts: Anstatt den Befehl direkt auszuführen, umhüllen Sie ihn mit
eval
:eval "$CMD"
-
Vorteile der Verwendung von
eval
:- Leerzeichen in Pfaden: Es ermöglicht, dass Pfade mit Leerzeichen (wie
Programme Dateien
) korrekt behandelt werden, da es die gesamte Zeichenfolge innerhalb der Anführungszeichen als einen einzigen Befehl auswertet. - Escape-Behandlung: Die Verwendung von
eval
kann helfen, sicherzustellen, dass Escape-Sequenzen angemessen behandelt werden, wodurch das Risiko von unbeabsichtigten Zeichenübersetzungen wie die\t
, die in einen Tabulator umgewandelt wird, verringert wird.
- Leerzeichen in Pfaden: Es ermöglicht, dass Pfade mit Leerzeichen (wie
-
Testen: Testen Sie Ihr Skript nach dieser Anpassung mit verschiedenen Eingaben, insbesondere solchen mit Leerzeichen und Escape-Zeichen, um sicherzustellen, dass alles wie erwartet funktioniert.
Beispiel für das endgültige Skript
So könnte Ihr überarbeitetes Shell-Skript aussehen:
#! /bin/sh
if [ "${1+set}" != "set" ]
then
echo "Verwendung; winewrap EXEC [ARGS...]"
exit 1
fi
EXEC="$1"
shift
ARGS=""
for p in "$@"; do
if [ -e "$p" ]; then
p=$(winepath -w "$p")
fi
ARGS="$ARGS '$p'"
done
CMD="wine '$EXEC' $ARGS"
echo $CMD
eval "$CMD"
Fazit
Das Anführen von Befehlszeilenargumenten in Shell-Skripten ist eine kritische Fähigkeit, insbesondere beim Umgang mit komplexen Anwendungs-Pfaden in Umgebungen wie WINE. Durch die Verwendung von eval
können Sie häufige Fehler im Zusammenhang mit Leerzeichen und falsch interpretierten Escape-Zeichen umgehen, sodass Ihre Skripte reibungslos und effizient ausgeführt werden.
Experimentieren Sie gerne mit Ihren Skripten und teilen Sie weitere Erkenntnisse oder Fragen in den Kommentaren unten!