我有一个生成文件其中,除其他外,安装 Bash 补全脚本:
install [...] /etc/bash_completion.d/
这在 Ubuntu 中工作得很好,但在 Arch Bash 中补全被安装到/usr/share/bash-completion/completions
.
会是什么惯用的 GNU 或 POSIXmake
方式来处理这个?我希望一个好的解决方案具有以下功能:
- 如果
install
命令失败,则目标也必定失败。 - 按书写顺序遍历目录列表。在第一个已经存在的目录处(如果有):
- 如果文件不存在则安装,
- 如果文件存在且不是最新的(根据
make
语义),则覆盖该文件, - 如果文件存在并且是最新的,则跳过该文件,并且
- 停止处理目录。
- 这是不是如果该文件未安装在任何地方,则会出现错误。
这是不是
Makefile
如果该文件已安装在一个目录中,并且后续运行将其安装到另一个目录中,则会出现错误(也不应尝试处理这种情况)。也就是说,给定一个目录列表/a /b
,如果有人- 创造
/b
, - 将文件放入
/b
, - 然后创建
/a
和 - 运行
make
应该
Makefile
不是/b
检测到所有的存在。- 创造
- 这是不是如果任何目录都不存在,则会出现错误。
- 关于尝试了哪些目录的反馈会很好,但不是强制性的。
答案1
显而易见的脚本式解决方案是这样做:
for dir in /etc/bash_completion.d /usr/share/bash-completion/completions; \
do \
if [ -d "$$dir" ]; \
then \
install [...] "$$dir" || exit 1; \
break; \
fi; \
done
然而,这不太好:
- 很多转义字符
- 需要使用ugly
|| exit 1
来检查错误
并且它不会检查文件是否是最新的(第 2.2、2.3 点)。
答案2
一种简单的方法是依次尝试每个安装并继续进行,直到其中一个安装成功为止。
for d in /etc/bash_completion.d /usr/share/bash-completion/completions; do \
{ cmp -s $(COMPLETION_SCRIPT) $$d/$(COMPLETION_SCRIPT) || \
install $(INSTALL_OPTIONS) $(COMPLETION_SCRIPT) $$d; } && exit; \
done; \
exit 1