BASH fügt Quelldateien in die Hauptquelle ein

BASH fügt Quelldateien in die Hauptquelle ein

Ich habe ein ziemlich großes BASH-Projekt, das ich zur besseren Lesbarkeit in mehrere Dateien aufgeteilt habe. Daher enthält die Hauptdatei viele sourceAnweisungen.

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.bashusw. 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.

sourceDie 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.bashund sucht nach einer sourceAnweisung. Wenn keine Übereinstimmung gefunden wird, wird diese Zeile einfach in die monolithic.bashDatei kopiert. Wenn jedoch eine sourceZeile gefunden wird, wird der Dateiname extrahiert und der Inhalt dieser Datei wird monolithic.bashanstelle der ursprünglichen sourceZeile 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 sourceZeile
  • plus: wendet automatisch die gleiche Einrückung auf den Inhalt der Quelldatei an, die vor der sourceAnweisung gefunden wurde (keine, wenn sourcedie Zeile nicht eingerückt war, wie in Ihrem Beispiel)

verwandte Informationen