Mir wurde ein %post-Skript in einer Spezifikationsdatei bereitgestellt, um eine Konfigurationsdatei (mit dem Namen foo) zu bearbeiten. Ich wurde beauftragt, ein weiteres, fast identisches Skript zu schreiben, um eine Datei mit dem Namen „bar“ zu bearbeiten.
Meine Lösung für „bar“ funktioniert zwar technisch, unterscheidet sich aber semantisch erheblich. Der Verwalter bittet mich, sie der Einheitlichkeit halber neu zu schreiben.
foo.groovy vorher
messageQueue.secretKey = "<ENTER-KEY-HERE>"
foo.groovy nach
messageQueue.secretKey = "y775hUYKR1Bm4gUWNRbzqg65"
Das mir gegebene Skript lautet wie folgt:
%define oauth_client_Secret \
echo " Setting the message queue secret key..." \
MESSAGEQUEUESECRETKEY=`dd if=/dev/urandom count=16 bs=1 2>/dev/null | base64` \
for config_file in `find /opt/foo/etc -name *.groovy` \
do \
sed -i -e "/messageQueue.secretKey/ { " \\\
-e " s?^//\s*??" \\\
-e " s?<ENTER-KEY-HERE>?${MESSAGEQUEUESECRETKEY}?" \\\
-e "}" \\\
${config_file} \
done
Was ich versuche herauszufinden:
- Was macht dieser reguläre Ausdruck?
s?^//\s*??"
Ich nehme an, er sucht nach einem Gleichheitszeichen? - Was ist der Zweck der abschließenden Schrägstriche?
\\\
- Warum hat der vorherige Autor den Ausdruck in Klammern gesetzt
{ }
?
Als Referenz ist hier mein Skript (für Bar), das ich versuche, so umzuschreiben, dass es dem obigen Skript (für Foo) entspricht.
bar.groovy vorher
clientSecret:"<ENTER-CLIENTSECRET-HERE>",
bar.groovy nach
clientSecret:"4gUWNRbzqg65y775hUYKR1Bm",
Balkenskript
%define oauth_client_Secret \
echo " Generating oauth clientSecret..." \
MESSAGEQUEUESECRETKEY=`dd if=/dev/urandom count=16 bs=1 2>/dev/null | base64` \
for config_file in `find /opt/bar/etc -name *.groovy` \
do \
sed -i "s/<ENTER-CLIENTSECRET-HERE>/${MESSAGEQUEUESECRETKEY}/g" ${config_file} \
done
Antwort1
In jeder Zeile, die den String enthält, messageQueue.secretKey
entfernt es den String //
und alle darauf folgenden Leerzeichen, wenn sie am Anfang der Zeile vorhanden sind, und ersetzt das erste Vorkommen von <ENTER-KEY-HERE>
durch den Inhalt der Shell-Variable ${MESSAGEQUEUESECRETKEY}
. Die {
Curlys beschränken die Entfernungen/Ersetzungen aufnurZeilen, die die Zeichenfolge enthalten messageQueue.secretKey
. Diese Operationen werden auf der Datei ausgeführt, auf die durch die Shell-Variable verwiesen wird${config_file}.
Die \\\
Backslashs setzen die Anweisung in einer langen Zeile fort und maskieren das unmittelbar folgende \n
Ewline-Zeichen, wenn das Skript von der Shell eingelesen wird. Drei sind notwendig, da diese in "
Anführungszeichen stehen und der Backslash sich in diesem Kontext selbst maskiert. Die Shell erhält also eine maskierte Zeilenumbruchzeile und sed
eine maskierte Zeilenumbruchzeile. Obwohl ich nicht weiß, wie es der Shell in diesem Kontext geht, glaube ich nicht, dass es sed
ihr etwas ausmachen würde, wenn die Zeilenumbrüche überhaupt nicht maskiert würden.
Antwort2
- Was macht dieser reguläre Ausdruck?
s?^//\s*??"
Entfernen Sie in Zeilen, die messageQueue.secretKey enthalten, das //
und alle auf den Zeilenanfang folgenden Leerzeichen mit:
- das Fragezeichen
?
als Mustertrennzeichen ^
entspricht dem Anfang einer Zeile//
stimmt genau damit überein (nebenbei bemerkt ist das der Grund, warum man als Mustertrennzeichen das Fragezeichen anstelle des gebräuchlicheren verwendet,/
das ziemlich viel Escape verhindert, weil sonst der reguläre Ausdrucks/^\/\/\s*//
\s*
ist GNU sed spezifisch für match oder oder mehr Leerzeichen spaceund/oder Tab; POSIX sed würde verwenden[:space:]
Und @mikeserv hat gerade eine noch umfassendere Antwort gepostet …