给hello-traditional Debian包添加postinst脚本后未执行的问题排查
问题:hello-traditional Debian包添加postinst脚本后未被执行
我尝试给标准的hello-traditional Debian包添加postinst脚本,步骤如下:
- 下载并解压该包,在
debian目录中添加了一个仅输出字符串的基础postinst脚本:
#!/bin/sh # This `DEBIAN/postinst` script is run post-installation set -e echo "Prova..............." exit 0
- 使用以下命令本地重建包:
dpkg-buildpackage -uc -us
或
debuild -us -uc
但测试安装时,postinst脚本未被调用,无法看到echo输出。
附原包中的rules文件:
#!/usr/bin/make -f # Sample debian/rules file - for GNU Hello. # Copyright 1994,1995 by Ian Jackson. # I hereby give you perpetual unlimited permission to copy, # modify and relicense this file, provided that you do not remove # my name from the file itself. (I assert my moral right of # paternity under the Copyright, Designs and Patents Act 1988.) # This file may have to be extensively modified package = hello-traditional docdir = debian/tmp/usr/share/doc/$(package) BUILD_DATE := $(shell dpkg-parsechangelog -S Date) CFLAGS := `dpkg-buildflags --get CFLAGS` -Wall LDFLAGS := `dpkg-buildflags --get LDFLAGS` CPPFLAGS := `dpkg-buildflags --get CPPFLAGS` STRIP = true export DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) export DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) export AM_UPDATE_INFO_DIR = no # Recommended snippet for Autoconf 2.52 or later ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE)) confflags += --build $(DEB_HOST_GNU_TYPE) stripcmd = strip else confflags += --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE) stripcmd = $(DEB_HOST_GNU_TYPE)-strip endif ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) STRIP = $(stripcmd) --remove-section=.comment --remove-section=.note endif build: ./configure CFLAGS="$(CFLAGS)" CPPFLAGS="$(CPPFLAGS)" \ LDFLAGS="$(LDFLAGS)" $(confflags) --prefix=/usr $(MAKE) touch build clean: rm -f build [ ! -f Makefile ] || $(MAKE) distclean rm -rf *~ debian/tmp debian/*~ debian/files* debian/substvars binary-indep: build # There are no architecture-independent files to be uploaded # generated by this package. If there were any they would be # made here. binary-arch: build rm -rf debian/tmp install -d debian/tmp/DEBIAN $(docdir) $(MAKE) prefix="$$(pwd)/debian/tmp/usr" install $(STRIP) debian/tmp/usr/bin/hello cp -a NEWS debian/copyright $(docdir) cp -a debian/changelog $(docdir)/changelog.Debian cp -a ChangeLog $(docdir)/changelog cd $(docdir) && gzip -9n changelog changelog.Debian gzip -r9n debian/tmp/usr/share/man gzip -9n debian/tmp/usr/share/info/* dpkg-shlibdeps debian/tmp/usr/bin/hello dpkg-gencontrol cd debian/tmp && \ find * -type f ! -regex "DEBIAN/.*" -print0 |\ LC_ALL=C sort -z | xargs -0r md5sum > DEBIAN/md5sums chown -R 0:0 debian/tmp chmod -R u+w,go=rX debian/tmp find debian/tmp -newermt '$(BUILD_DATE)' -print0 |\ xargs -0r touch -h --date='$(BUILD_DATE)' dpkg --build debian/tmp .. binary: binary-indep binary-arch build-arch: build build-indep: build .PHONY: binary binary-arch binary-indep build-arch build-indep clean
原因与解决方法
核心原因
你把postinst脚本放在了debian目录下,但从rules文件的binary-arch步骤可以看到,构建过程是直接在debian/tmp/DEBIAN目录下组装包的,但没有将debian目录下的postinst脚本复制到debian/tmp/DEBIAN目录中。Debian包的维护脚本(postinst、prerm等)必须存在于最终构建目录的DEBIAN子目录下,才会被打包进deb包并在安装时执行。
解决步骤
- 调整脚本位置(可选):建议将postinst脚本命名为
debian/hello-traditional.postinst(格式为debian/<包名>.postinst),这是Debian包维护的标准命名方式,便于后续管理。 - 修改rules文件:在
binary-arch步骤里,找到install -d debian/tmp/DEBIAN $(docdir)这一行之后,添加复制脚本的命令:
如果用了标准命名,则改为:install -m 755 debian/postinst debian/tmp/DEBIAN/
注意必须给脚本设置755权限,否则dpkg会拒绝执行它。install -m 755 debian/$(package).postinst debian/tmp/DEBIAN/postinst - 重新构建验证:再次运行
dpkg-buildpackage -uc -us或debuild -us -uc生成新包,安装后即可看到echo的输出。
额外验证方法
- 用
dpkg-deb -c <生成的deb包>查看包内容,确认./DEBIAN/postinst存在且权限为755; - 用
dpkg-deb -e <deb包> <临时目录>提取DEBIAN目录,直接检查脚本是否存在。
内容的提问来源于stack exchange,提问作者LPs
相关产品推荐
相关产品推荐

