Marc Haber <
mh+usene...@zugschl.us>:
So, wie du es am Ende, also in «keks», mit der Kommandozeile
$(CMD}
aufrufst, gibt es für «keks-config» keine Möglichkeit, es richtig
zu machen: Quoting ist eine Sache des Kommandozeilenparsers.
Ehe die Variable «CMD» in der angeführten Kommandozeile
expandiert wird, ist der Parser schon gelaufen. Irgendwelche
Apostrophe, Anführungszeichen oder umgekehrte Schrägstriche
spielen deshalb im Inhalt der Variablen «CMD» keine Rolle mehr.
Das einzige, was da noch geschieht, ist das Zerbrechen des
Inhalts der Variablen «CMD» an allen Stellen, an denen ein
Zeichen aus der in der Variablen «IFS» aufgezählten Zeichen
sitzt, weil du die Expansion ohne Anführungszeichen aufrufst.
Um es richtig hinzubekommen, muss man erstens das Zerbrechen
verhindern, also «"${CMD}"» anstelle von «${CMD}» verwenden, und
zweitens den Parser nochmals anwerfen, indem man «eval»
verwendet:
eval "${CMD}"
Dann kann und muss(!) man beim Belegen der Variablen «CMD» dafür
sorgen, dass der Inhalt der Variablen «CMD» eine Kommandozeile
wird – mitsamt allen notwendigen Quoting‐ und Escape‐Zeichen.
In «keks-config» kann also beispielsweise folgendes stehen:
CMD='./keks-show --from='\''bar <baz@example>'\'' bum'
Dann erhält die Variable «CMD» den folgenden Inhalt:
./keks-show --from='bar <baz@example>' bum
Das ist eine Kommandozeile, wie du sie haben möchtest. (Prüfe
mit dem Kommando
printf '==]%s[==\n' "$CMD"
nach, dass die Variable «CMD» wirklich diesen Text enthält.)
Natürlich will man so eine Zuweisung an die Variable «CMD» nicht
gerne von Hand («Quoting‐Hölle») austüfteln. Als Abhilfe schnapp
dir die Funktion «my_quote_words_for_shells» aus dem News‐Beitrag
Subject: Re: Robuste Pfade
From: Helmut Waitzmann <
nn.th...@xoxy.net>
Newsgroups: de.comp.os.unix.shell
Date: Tue, 30 Aug 2022 19:55:40 +0200
Message-ID: <
83fshdp...@helmutwaitzmann.news.arcor.de>
und stell sie in eine Datei, beispielsweise
«~/shell-lib/my_quote_words_for_shells.sh». Dann schreibe in die
Datei «keks-config»
CMD="$( . ~/shell-lib/my_quote_words_for_shells.sh &&
my_quote_words_for_shells \
./keks-show --from='bar <baz@example>' bum
)"
Prüfe nochmals mit dem Kommando
printf '==]%s[==\n' "$CMD"
nach, dass die Variable «CMD» eine passende Kommandozeile
enthält. Dann sollte anschließend in der Datei «keks» die
Kommandozeile
eval "$CMD"
tun, was du willst.
--
Hat man erst verstanden, wie Unix funktioniert, ist auch
das Shell-Handbuch kein Buch mit sieben Siegeln mehr.