创建一个打包的目录,类似rpmbuild,这里创建了目录deb_build
目标
我有一个hello的二进制文件hello和源码hello.c, 准备安装到/opt/helloworld目录中
步骤
- 在deb_build目录创建一个文件夹用于存放我的安装文件
- 在helloworld文件里创建DEBIAN文件夹和opt文件夹
- 在DEBIAN文件夹创建一个文件control
- 在opt文件夹新建一个helloworld文件夹,存放上hello和hello.c,如下
| $ tree helloworld/ |
| helloworld/ |
| ├── DEBIAN |
| │ └── control |
| └── opt |
| └── helloworld |
| ├── hello |
| └── hello.c |
| |
| 3 directories, 3 files |
control文件类似rpm的spec文件,包含deb的包信息
只要把想安装的文件写到对应目录就可以安装到对应的系统目录
这里描述一个最简易的control文件
| Package: helloworld |
| Description: my deb test |
| Maintainer: username <user@mail.com> |
| Version: 0.1 |
| Architecture: all |
- 回到deb_build目录,执行
dpkg -b helloworld
即可在当前目录生成deb包
| $ dpkg -b helloworld |
| dpkg-deb: building package 'hello' in 'helloworld.deb'. |
也可以指定dpkg -b hellorld hellorld-0.1-all.deb
| $ dpkg -b helloworld helloworld-0.1-all.deb |
| dpkg-deb: building package 'helloworld' in 'helloworld-0.1-all.deb'. |
- 观看deb包的信息
| 查看包的字段信息: |
| $ dpkg -f helloworld-0.1-all.deb |
| Package: helloworld |
| Description: my deb test |
| Maintainer: WangLin <email@163.com> |
| Version: 0.1 |
| Architecture: all |
| 查看deb包的详细信息: |
| $ dpkg -I helloworld-0.1-all.deb |
| new Debian package, version 2.0. |
| size 2804 bytes: control archive=296 bytes. |
| 112 bytes, 5 lines control |
| Package: helloworld |
| Description: my deb test |
| Maintainer: WangLin <email@163.com> |
| Version: 0.1 |
| Architecture: all |
| 查看deb包中的文件列表: |
| $ dpkg -c helloworld-0.1-all.deb |
| drwxrwxr-x wanglin/wanglin 0 2023-01-11 07:51 ./ |
| drwxrwxr-x wanglin/wanglin 0 2023-01-11 07:54 ./opt/ |
| drwxrwxr-x wanglin/wanglin 0 2023-01-11 07:54 ./opt/helloworld/ |
| -rwxrwxr-x wanglin/wanglin 8304 2023-01-11 07:53 ./opt/helloworld/hello |
| -rw-rw-r-- wanglin/wanglin 100 2023-01-11 07:53 ./opt/helloworld/hello.c |
- 安装打好的deb包
| $ sudo dpkg -i helloworld-0.1-all.deb |
| Selecting previously unselected package helloworld. |
| (Reading database ... 208913 files and directories currently installed.) |
| Preparing to unpack helloworld-0.1-all.deb ... |
| Unpacking helloworld (0.1) ... |
| Setting up helloworld (0.1) ... |
此时/opt/helloworld/hello和hello.c 就安装在/opt/helloworld目录下了
检测安装效果
| $ dpkg -l helloworld |
| Desired=Unknown/Install/Remove/Purge/Hold |
| | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend |
| |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad) |
| ||/ Name Version Architecture Description |
| +++-=======================-================-================-=================================================== |
| ii helloworld 0.1 all my deb test |
| $ ls /opt/helloworld/ |
| hello hello.c |
| |
| $ sudo /opt/helloworld/hello |
| hello world |
| $ dpkg -s helloworld |
| Package: helloworld |
| Status: install ok installed |
| Maintainer: WangLin <email@163.com> |
| Architecture: all |
| Version: 0.1 |
| Description: my deb test |
- 查看/var/lib/dpkg/status中的记录
| $ cat /var/lib/dpkg/status|grep helloworld -A 5 |
| Package: helloworld |
| Status: install ok installed |
| Maintainer: WangLin <email@163.com> |
| Architecture: all |
| Version: 0.1 |
| Description: my deb test |
| $ dpkg -L helloworld |
| /. |
| /opt |
| /opt/helloworld |
| /opt/helloworld/hello |
| /opt/helloworld/hello.c |
附录
control文件字段描述
字段 |
用途 |
例子其他 |
Package |
程序名称 |
中间不能有空格 |
Version |
软件版本 |
|
Description |
程序说明 |
|
Section |
软件类别 |
utils,net,mail,text,x11 |
Priority |
软件对于系统的重要程度 |
required,standard,optional,extra等 |
Essential |
是否是系统最基本的软件包 |
yes/no,若为yes,则不允许卸载(除非强制性卸载) |
Architecture |
软件所支持的平台架构 |
i386,amd64,m68k,sparc,alpha,powerpc等 |
Source |
软件包的源代码名称 |
|
Depends |
软件所依赖的其他软件包和库文件 |
若依赖多个软件包和库文件,采用逗号隔开 |
Pre-Depends |
软件安装前必须安装、配置依赖性的软件包和库文件 |
常用语必须得预运行脚本需求 |
Recommends |
推荐安装的其他软件包和库文件 |
|
Suggests |
建议安装的其他软件包和库文件 |
|
Maintainer |
作者 <邮箱或者其他联系方式> |
|
Descritprion |
简介,可以换行书写 |
|
contol架构字段
name |
arch |
amd64 |
x86架构CPU |
any |
包含编译型语言编写的程序生成的二进制包依賴于具体体系结构 |
all |
包含文本、图像、或解释性语言脚本生成的二进制包独立于体系结构 |
可以通过命令dpkg-architecture -L
看到所有架构名称
控制文件的描述信息
控制文件 |
描述 |
control |
用了记录软件标识,版本号,平台,依赖信息等数据 |
preinst |
判断是upgrade还是普通安装的脚本 |
postinst |
安装包完成后需要做的动作,比如起服务 |
prerm |
卸载时,在删除文件之前运行的脚本 |
postrm |
在删除文件之后运行的脚本 |
preinst,postinst,prerm,postrm等脚本的内容可以通过dh_make -s -y
命令创建的debian目录中创建,有样例文件内容
dh_make需要在-的目录下使用,即创建一个name-1.0这样的目录下
DEBIAN/preinst样例
| #!/bin/sh |
| set -e |
| |
| case "$1" in |
| install) |
| rm -rf /opt/helloworld |
| ;; |
| |
| upgrade) |
| if [ -e /opt/helloworld ]; then |
| rm -f /opt/helloworld |
| fi |
| ;; |
| |
| abort-upgrade) |
| ;; |
| |
| *) |
| echo "preinst called with unknown argument \`$1'" >&2 |
| exit 1 |
| ;; |
| esac |
| exit 0 |
DEBIAN/postinst样例
| #!/bin/sh |
| set -e |
| |
| case "$1" in |
| configure) |
| ;; |
| |
| abort-upgrade|abort-remove|abort-deconfigure) |
| ;; |
| |
| *) |
| echo "postinst called with unknown argument \`$1'" >&2 |
| exit 1 |
| ;; |
| esac |
| exit 0 |
DEBIAN/prerm
| #!/bin/sh |
| set -e |
| if [ "$1" = remove ]; then |
| ... |
| fi |
DEBIAN/postrm
| #!/bin/sh |
| set -e |
| |
| case "$1" in |
| purge) |
| |
| ;; |
| |
| upgrade|remove|failed-upgrade|abort-install|abort-upgrade|disappear) |
| ;; |
| |
| *) |
| |
| exit 1 |
| ;; |
| esac |
| |
| if [ "$1" = "remove" ]; then |
| ... |
| fi |
| |
| if [ "$1" = "purge" ]; then |
| ... |
| fi |
| |
| exit 0 |
Install的执行过程
| Selecting previously unselected package testdeb. |
| Preparing to unpack testdeb.deb ... |
| in preinst |
| /bin/bash |
| args: install, argc: 1 |
| Unpacking testdeb (0.1.1) ... |
| Setting up testdeb (0.1.1) ... |
| in postinst |
| /bin/bash |
| args: configure , argc: 2 |
preinst: 传入参数1个为install
postinst: 传入参数两个,第一个是configure,第二个是空
Upgrade的执行过程
| Preparing to unpack testdeb-0.1.2.deb ... |
| in prerm |
| /bin/bash |
| args: upgrade 0.1.2, argc: 2 |
| in preinst |
| /bin/bash |
| args: upgrade 0.1.1 0.1.2, argc: 3 |
| Unpacking testdeb (0.1.2) over (0.1.1) ... |
| in postrm |
| /bin/bash |
| args: upgrade 0.1.2, argc: 2 |
| Setting up testdeb (0.1.2) ... |
| in postinst |
| /bin/bash |
| args: configure 0.1.1, argc: 2 |
prerm: 传入参数两个: 第一个是upgrade,第二个是版本号
preinst: 传入参数三个,第一个是upgrade,第二个是当前版本号,第三个是升级安装的版本号
postrm: 传入参数两个,第一个是upgrade, 第二个是新的版本号
postinst: 传入两个参数,第一个是configure,第二个是旧的版本号
Purge的执行过程
| Removing testdeb (0.1.2) ... |
| in prerm |
| /bin/bash |
| args: remove, argc: 1 |
| in postrm |
| /bin/bash |
| args: remove, argc: 1 |
| Purging configuration files for testdeb (0.1.2) ... |
| in postrm |
| /bin/bash |
| args: purge, argc: 1 |
prerm: 参数一个: remove
postrm第一遍: 参数一个: remove
postrm第二遍: 参数一个purge
Remove的执行过程
| Removing testdeb (0.1.2) ... |
| in prerm |
| /bin/bash |
| args: remove, argc: 1 |
| in postrm |
| /bin/bash |
| args: remove, argc: 1 |
prerm: 参数一个: remove
postrm: 参数一个remove
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)