より読みやすくするために、複数のファイルに分割されたかなり大きな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
行で発生する可能性のある空白の問題を通常無視します。 - プラス:ステートメントの前と同じ量のインデントをソースファイルの内容に自動的に適用します
source
(source
例のように、行がインデントされていない場合はインデントなし)。