
Ich habe ein ziemlich großes BASH-Projekt, das ich zur besseren Lesbarkeit in mehrere Dateien aufgeteilt habe. Daher enthält die Hauptdatei viele source
Anweisungen.
Jetzt veröffentliche ich es auf GitHub und schreibe ein Installationsskript dafür. Das Problem ist, dass das Erstellen von Unterverzeichnissen unter Binärordnern (genauer gesagt /usr/local/sbin
) vom FHS verboten ist und ich Binärordner nicht mit mehreren Dateien wie main.bash
config.bash
usw. durcheinander bringen möchte.
Als Lösung dachte ich, dass ich, wenn das Installationsskript diese Dateien zusammenführen würde, eine große, monolithische BASH-Datei erhalten würde, die überall auf dem System abgelegt werden kann.
source
Die Frage ist: Wie kann ich alle Anweisungen in meinem Hauptskript durch den Inhalt der Quelldateien ersetzen ?
Beispiel:
inbegriffen.bash
echo "bar"
main.bash
echo "foo"
source included.bash
Resultierende monolithische Datei
echo "foo"
echo "bar"
Antwort1
Dieses Skript, das beispielsweise aufgerufen werden könnte make-monolithic.bash
, durchläuft jede Zeile in main.bash
und sucht nach einer source
Anweisung. Wenn keine Übereinstimmung gefunden wird, wird diese Zeile einfach in die monolithic.bash
Datei kopiert. Wenn jedoch eine source
Zeile gefunden wird, wird der Dateiname extrahiert und der Inhalt dieser Datei wird monolithic.bash
anstelle der ursprünglichen source
Zeile in kopiert.
#!/usr/bin/env bash
readonly MAIN="main.bash"
readonly MONOLITHIC="monolithic.bash"
[ -f "$MONOLITHIC" ] && cp "$MONOLITHIC" "${MONOLITHIC}.bak"
## to extract sourced filename
regex='^\([[:space:]]*\)source[[:space:]]\+\([^[:space:]]\+\)[[:space:]]*$'
IFS=$'\n' ## retain whitespace
while read main_line; do
sourced=$(echo "$main_line" | sed -n "s/$regex/\2/p")
if [ -n "$sourced" ]; then
indent=$(echo "$main_line" | sed -n "s/$regex/\1/p")
while read sourced_line; do
echo "${indent}${sourced_line}" >> "$MONOLITHIC"
done < "$sourced"
else
echo "$main_line" >> "$MONOLITHIC"
fi
done < "$MAIN"
unset IFS
[ -f "${MONOLITHIC}.bak" ] && rm "${MONOLITHIC}.bak"
- getestet an Ihrem bereitgestellten Beispiel
- ignoriert auch problemlos mögliche Leerzeichen in der
source
Zeile - plus: wendet automatisch die gleiche Einrückung auf den Inhalt der Quelldatei an, die vor der
source
Anweisung gefunden wurde (keine, wennsource
die Zeile nicht eingerückt war, wie in Ihrem Beispiel)