BASHソースファイルをデフォルトソースに貼り付ける

BASHソースファイルをデフォルトソースに貼り付ける

より読みやすくするために、複数のファイルに分割されたかなり大きなBASHプロジェクトがあります。したがって、基本ファイルには多くのsource文が含まれています。

私はGitHubに投稿し、それのためのインストーラスクリプトを書いています。問題は、FHSがバイナリフォルダの下にサブディレクトリを作成することを禁止し(正確に言うと)、バイナリフォルダを複数のファイル(など)に複雑にしたくないこと/usr/local/sbinです。main.bash config.bash

解決策として、インストーラスクリプトがこれらのファイルをマージすると、システムのどこにでも配置できる単一の大きなBASHファイルが1つあると思いました。

問題は、source基本スクリプトのすべての文をソースファイルの内容に置き換える方法です。

例:

.bashを含みます。

echo "bar"

main.bash

echo "foo"
source included.bash

生成されたファイル全体

echo "foo"
echo "bar"

答え1

スクリプトは呼び出すことができ、make-monolithic.bash各行を通過してステートメントをmain.bash見つけますsource。一致するものがない場合は、その行をファイルにコピーしますmonolithic.bash。ただし、source行が見つかると、ファイル名が抽出され、ファイルの内容がmonolithic.bash元の行の代わりにコピーされますsource

#!/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"
  • 提供された例でテストされました。
  • また、source行で発生する可能性のある空白の問題を通常無視します。
  • プラス:ステートメントの前と同じ量のインデントをソースファイルの内容に自動的に適用しますsourcesource例のように、行がインデントされていない場合はインデントなし)。

関連情報