BASH cola os arquivos de origem na fonte principal

BASH cola os arquivos de origem na fonte principal

Eu tenho um projeto BASH bastante grande, que divido em vários arquivos para torná-lo mais legível. Como resultado, o arquivo principal contém muitas sourceinstruções.

Agora estou lançando-o no GitHub e escrevendo um script de instalação para ele. O problema é que a criação de subdiretórios em pastas binárias (exatamente /usr/local/sbin) é proibida pela FHS e não quero bagunçar pastas binárias com vários arquivos como main.bash config.bash, etc.

Como solução, pensei que se o script do instalador mesclasse esses arquivos, eu obteria um arquivo BASH grande e monolítico, que pode ser colocado em qualquer lugar do sistema.

A questão é: como posso substituir todas sourceas instruções do meu script principal pelo conteúdo dos arquivos de origem?

Exemplo:

incluído.bash

echo "bar"

principal.bash

echo "foo"
source included.bash

Arquivo monolítico resultante

echo "foo"
echo "bar"

Responder1

Este script, que pode ser chamado de make-monolithic.bash, percorrerá cada linha main.bashe procurará uma sourceinstrução. Se não houver correspondência, basta copiar essa linha para o monolithic.basharquivo. No entanto, se uma sourcelinha for encontrada, o nome do arquivo será extraído e o conteúdo desse arquivo será copiado para monolithic.bash, em vez da sourcelinha original.

#!/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"
  • testado no seu exemplo fornecido
  • também ignora possíveis problemas de espaço em branco na sourcelinha
  • mais: aplica automaticamente a mesma quantidade de recuo ao conteúdo do arquivo de origem encontrado antes da sourceinstrução (nenhum, se sourcea linha não foi recuada, como no seu exemplo)

informação relacionada