我有一个相当大的 BASH 项目,我将其分成多个文件以使其更具可读性。因此,主文件包含许多source
语句。
现在我正在 GitHub 上发布它,并为其编写安装程序脚本。问题是,/usr/local/sbin
FHS 禁止在二进制文件夹(确切地说)下创建子目录,我不想用多个文件(如main.bash
config.bash
等)弄乱二进制文件夹。
作为一种解决方案,我认为如果安装程序脚本将这些文件合并在一起,我将得到一个大型的整体 BASH 文件,该文件可以放置在系统上的任何位置。
问题是:如何用source
源文件的内容替换主脚本中的所有语句?
例子:
包含.bash
echo "bar"
主.bash
echo "foo"
source included.bash
生成的整体文件
echo "foo"
echo "bar"
答案1
该脚本可能被称为make-monolithic.bash
,它将遍历 in 中的每一行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
行未缩进,则无缩进,如您的示例所示)