2. Linux制作deb包的方法¶
为了方便管理一些程序或脚本,可以将这些程序以及脚本都制作在一个deb包中, 本章节将介绍如何制作一个deb包, 制作deb的方式很多,如使用dpkg-deb方式、使用checkinstall方式、使用dh_make方式及修改原有的deb包, 本章将介绍如何从零制作一个自己的deb包,以及修改原有的deb包。
2.1. 什么是deb包?¶
deb包是在linux系统下的一种安装包,有时我们在网上下载的Linux软件安装包也会以deb包的形式出现, 由于它是基于tar包的,所以同样会记录着文件的权限信息(读、写、可执行)、所有者、用户组等。
我们可以使用命令:dpkg -l 来查看系统以及安装了哪些deb包。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | root@npi:/home/debian# dpkg -l
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 Architectu
+++-=============================-===================================-==========
ii adduser 3.118 all
ii apt 1.8.2.2 arm64
ii apt-transport-https 1.8.2.2 all
ii apt-utils 1.8.2.2 arm64
ii avahi-daemon 0.7-4+deb10u1 arm64
ii base-files 10.3+deb10u9 arm64
ii base-passwd 3.5.46 arm64
ii bash 5.0-4 arm64
ii bind9-host 1:9.11.5.P4+dfsg-5.1+deb10u3 arm64
ii bsdmainutils 11.1.2+b1 arm64
ii bsdutils 1:2.33.1-0.1 arm64
ii busybox 1:1.30.1-4 arm64
ii ca-certificates 20200601~deb10u2 all
ii connman 1.36-2.1~deb10u1 arm64
ii coreutils 8.30-3 arm64
ii cpio 2.12+dfsg-9 arm64
ii cron 3.0pl1-134+deb10u1 arm64
ii curl 7.64.0-4+deb10u1 arm64
lines 1-23
|
图中为野火linux开发板下所安装的deb包列表,Name所对应的列为已安装的deb包包名, Version表示该包的版本号,Architecture为该包所支持的处理器架构。
2.2. deb包的组成结构¶
deb包一般分成两部分:
安装的内容,这部分类似linux的根目录,表示需要将软件安装到linux系统上的文件目录。
控制信息(放在DEBIAN目录下),通常DEBIAN目录下有如下几个文件。
changelog: 文件记录了deb包的作者、版本以及最后一次更新日期等信息;
control: 文件记录了包名、版本号、架构、维护者及描述等信息;
copyright: 文件记录了一些版权信息;
postinst: 软件在进行正常目录文件拷贝到系统后需要执行的脚本。
postrm文件: 软件卸载后需要执行的脚本。
其中control、postinst、postrm为必要文件。
2.3. 从零开始创建自己的deb包¶
安装工具及依赖:
sudo apt-get install build-essential debhelper make autoconf automake dpkg-dev fakeroot pbuilder gnupg
首先我们创建如下目录及文件
1 2 3 4 5 6 7 8 | hello_deb/
├── DEBIAN
│ ├── control
│ ├── postinst
│ └── postrm
└── opt
└── hello_deb
└── hello_deb.sh
|
在hello_deb目录下创建DEBIAN及opt/hello_deb目录,DEBIAN目录下包含控制信息文件, 而在opt/hello_deb目录下创建hello_deb.sh文件则表示我们需要将hello_deb.sh文件安装到 linux系统的opt/hello_deb目录下。
然后分别给予postinst、postrm、hello_deb.sh文件以可执行权限。
其中control文件所包含信息如下:
1 2 3 4 5 6 7 8 9 | Package: hello-deb
Version: 1.0.0
Section: free
Priority: optional
Essential: no
Architecture: arm64
Maintainer: embedfire <embedfire@embedfire.com>
Provides: hell_deb
Description: deb test
|
若以后想升级这个deb包,可以修改该包的版本号Version,值得注意的是Architecture, 前面我们也有讲到,就是该deb包所支持的处理器架构, 因为最终要将该deb包安装到arm64开发板上,而arm64处理器架构为arm64, 所以我们应该在Architecture中填入arm64属性,大家可根据自己的需求做相应修改即可, 如果不知道你的处理器架可以通过dpkg -l命令来查看已安装的deb包持支的架构, 或者输入lscpu查看处理器信息,若想支持所有架构,可以填入all属性, 如果Architecture属性与当前处理器架构属性不匹配的话,deb包将无法成功安装, 且control的属性信息必须以字母或者数字开头,不然可能导致打包出错。
postinst文件包含信息如下:
1 2 3 4 5 | #!/bin/bash
if [ "$1" = "upgrade" ] || [ "$1" = "install" ];then
echo "hello_deb installing"
fi
|
当安装了该deb包以后,系统会默认执行postinst脚本, 通常我们利用该脚本来搭建一些为软件执行的环境(如创建目录、修改权限等), 值得注意的是该文件需具有可执行权限。 这里写的比较简单,判断第一个参数,仅供参考。
postrm文件包含信息如下:
1 2 3 4 5 6 7 8 | #!/bin/bash
if [ "$1" = "upgrade" ] ; then
echo "upgrade"
elif [ "$1" = "remove" ] || [ "$1" = "purge" ] ; then
echo "remove"
fi
|
当卸载了该deb包以后,系统会默认执行postrm脚本,通常我们利用该脚本来清理环境, 值得注意的是该文件具有可执行权限。 这里写的比较简单,判断第一个参数,仅供参考。
最后我们来看下真正的程序主体,为了简单起见,此处以一个简单的脚本为例。
1 2 3 4 | #! /bin/bash
echo Hello deb!
echo This is a test script!!!
|
脚本仅仅是打印两句信息,用户可自行设置需要执行的程序。
万事俱备,只欠东风,当备齐了制作deb包的基本原材料之后我们便可以开始制作属于自己的deb包了, 进入hello_deb目录下,也就是DEBIAN及home文件夹所在的目录,接着输入如下命令来构建软件包。
sudo dpkg-deb -b ../hello_deb ../hello_deb_1.0.0_arm64.deb
其中dpkg-deb是构建deb包命令,-b参数表示要构建一个deb包, ../hello_deb参数表示要构建deb包原材料的路径, ../hello_deb_1.0.0_arm64.deb参数表示将该deb包构建在当前目录的上级目录中, 一般我们构建deb包的名字都会遵循这么一个原则, 其命名方式为:软件名称+软件版本号+该软件所支持的处理器架构, 如软件名为hello_deb,版本号为1.0.0,所支持的处理器架构为arm64。
打包成功后会输出如下信息,并可在上级目录查看到deb安装包:
1 2 3 4 5 | qinghui@ebf-dev:~/deb/hello_deb$ sudo dpkg-deb -b ../hello_deb ../hello_deb_1.0.0_arm64.deb
dpkg-deb: 正在 '../hello_deb_1.0.0_arm64.deb' 中构建软件包 'hello-deb'。
qinghui@ebf-dev:~/deb/hello_deb$ ls ..
hello_deb hello_deb_1.0.0_arm64.deb
qinghui@ebf-dev:~/deb/hello_deb$
|
制作好自己的deb包后我们需要验证一下是否真的制作成功, 可以如下命令查看已制作的deb包文件内容:
1 2 3 4 5 6 7 8 | #命令
dpkg -c hello_deb_1.0.0_arm64.deb
#打印信息
drwxrwxr-x qinghui/qinghui 0 2021-04-15 11:16 ./
drwxrwxr-x qinghui/qinghui 0 2021-04-15 11:16 ./opt/
drwxrwxr-x qinghui/qinghui 0 2021-04-15 11:22 ./opt/hello_deb/
-rwxrwxr-x qinghui/qinghui 65 2021-04-15 11:22 ./opt/hello_deb/hello_deb.sh
|
也可使用如下命令查看deb包信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #命令
dpkg --info hello_deb_1.0.0_arm64.deb
#打印信息
new Debian package, version 2.0.
size 976 bytes: control archive=500 bytes.
190 字节, 9 行 control
100 字节, 7 行 * postinst #!/bin/bash
133 字节, 8 行 * postrm #!/bin/bash
Package: hello-deb
Version: 1.0.0
Section: free
Priority: optional
Essential: no
Architecture: arm64
Maintainer: embedfire <embedfire@embedfire.com>
Provides: hell_deb
Description: deb test
|
将该deb包拷贝到linux开发板的文件系统下, 输入“sudo dpkg -i hello_deb_1.0.0_arm64.deb”命令即可安装, 其中-i 参数表示安装软件,即install, 并且在安装完软件之后可以输入“dpkg -s hello-dev”命令查看是否安装了软件。 如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | root@npi:/home/debian# sudo dpkg -i hello_deb_1.0.0_arm64.deb
Selecting previously unselected package hello-deb.
(Reading database ... 12164 files and directories currently installed.)
Preparing to unpack hello_deb_1.0.0_arm64.deb ...
Unpacking hello-deb (1.0.0) ...
Setting up hello-deb (1.0.0) ...
root@npi:/home/debian# dpkg -s hello-deb
Package: hello-deb
Status: install ok installed
Priority: optional
Section: free
Maintainer: embedfire <embedfire@embedfire.com>
Architecture: arm64
Version: 1.0.0
Provides: hell_deb
Description: deb test
|
或者输入“dpkg -l | grep hello-deb”命令查看你的软件是否在已安装软件列表里面。
1 2 | root@npi:/home/debian# dpkg -l | grep hello-deb
ii hello-deb 1.0.0 arm64 deb test
|
验证安装完成之后查看开发板/opt/hello_deb目录下是否存在hello_deb.sh文件。
1 2 3 4 | root@npi:/home/debian# ls /opt/
backup hello_deb scripts source
root@npi:/home/debian# ls /opt/hello_deb/
hello_deb.sh
|
执行看看效果
1 2 3 | root@npi:/home/debian# /opt/hello_deb/hello_deb.sh
Hello deb!
This is a test script!!!
|
到此,制作deb包的基本流程已介绍完毕。
2.4. 从根据已有deb包修改内容¶
下面介绍下如何修改已有的deb包,以刚刚创建的deb包为例。
在已有的deb包目录下新建一个update_deb目录,使用 dpkg -X 命令对deb包进行解压。
1 2 3 4 5 6 7 8 9 10 | qinghui@ebf-dev:~/deb$ ls
hello_deb hello_deb_1.0.0_arm64.deb
qinghui@ebf-dev:~/deb$ mkdir update_deb
qinghui@ebf-dev:~/deb$ ls
update_deb hello_deb hello_deb_1.0.0_arm64.deb
qinghui@ebf-dev:~/deb$ dpkg -X hello_deb_1.0.0_arm64.deb update_deb/
./
./opt/
./opt/hello_deb/
./opt/hello_deb/hello_deb.sh
|
进入update_deb目录下可看到并没DEBIAN相关目录,在update_deb目录下使用 dpkg -e 解压出 控制相关信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | qinghui@ebf-dev:~/deb/update_deb$ ls
opt
qinghui@ebf-dev:~/deb/update_deb$ dpkg -e ../hello_deb_1.0.0_arm64.deb
qinghui@ebf-dev:~/deb/update_deb$ ls
DEBIAN opt
qinghui@ebf-dev:~/deb/update_deb$ tree
.
├── DEBIAN
│ ├── control
│ ├── postinst
│ └── postrm
└── opt
└── hello_deb
└── hello_deb.sh
3 directories, 4 files
qinghui@ebf-dev:~/deb/update_deb$
|
此时就可以对程序主体进行修改了,我们在opt/hello_deb/hello_deb.sh下添加一句打印消息, 如下所示
1 2 3 4 5 | #! /bin/bash
echo Hello deb!
echo This is a test script!!!
echo update deb!
|
修改DEBIAN/control下的版本信息,修改如下
1 2 3 4 5 6 7 8 9 | Package: hello-deb
Version: 1.0.1
Section: free
Priority: optional
Essential: no
Architecture: arm64
Maintainer: embedfire <embedfire@embedfire.com>
Provides: hell_deb
Description: deb test
|
此时便可以重新打包应用程序了。
1 2 | qinghui@ebf-dev:~/deb/update_deb$ sudo dpkg-deb -b ../update_deb ../hello_deb_1.0.1_arm64.deb
dpkg-deb: 正在 '../hello_deb_1.0.1_arm64.deb' 中构建软件包 'hello-deb'。
|
2.5. 简单实例:通过安装deb包创建开机自启服务¶
通过安装deb包在野火开发板上实现程序开机自启,在实际项目上的应用极为普遍, 不少的用户经常有这方面的困扰,下面通过一个简单的实例介绍相关如何使用创建开机自动的deb程序。
创建一个新的deb包目录,文件结构如下
1 2 3 4 5 6 7 8 9 10 11 12 | hello_deb
├── DEBIAN
│ ├── control
│ ├── postinst
│ └── postrm
├── etc
│ └── systemd
│ └── system
│ └── hello.service
└── opt
└── hello_deb
└── hello_deb.sh
|
其中 /etc/systemd/system/hello.service
为自启服务,
/opt/hello_deb/hello_deb.sh
为程序主体。
DEBIAN目录为deb包的一些描述信息以及安装卸载执行脚本等,对于一些基本概念此处便不再赘述,
直接查看各个文件中的内容。
DEBIAN/control文件内容如下所示
1 2 3 4 5 6 7 8 9 | Package: hello-deb
Version: 1.0.0
Section: free
Priority: optional
Essential: no
Architecture: arm64
Maintainer: embedfire <embedfire@embedfire.com>
Provides: hell_deb
Description: deb test
|
DEBIAN/postinst文件内容如下所示,脚本的内容很简单只是使能了hello相关服务并启动它。
1 2 3 4 5 6 | echo "......................................................"
echo "..............hello_deb installing...................."
echo "......................................................"
systemctl enable hello
systemctl start hello
|
DEBIAN/postinst文件内容如下所示,当卸载程序时,关闭hello相关服务。
1 2 3 4 5 6 | if [ "$1" = "upgrade" ] ; then
echo "upgrade"
elif [ "$1" = "remove" ] || [ "$1" = "purge" ] ; then
echo "remove"
systemctl disable hello
fi
|
/etc/systemd/system/hello.service服务内容如下,重点在于第六行,指定需要执行的程序。
1 2 3 4 5 6 7 8 9 10 11 | [Unit]
Description = hello daemon
[Service]
ExecStart = /opt/hello_deb/hello_deb.sh
Restart = always
Type = simple
[Install]
WantedBy = multi-user.target
|
/opt/hello_deb/hello_deb.sh为程序主体,内容如下所示,以每3秒的速度向/tmp/hello.log 写入Hello Embedfire。
1 2 3 4 5 6 7 | #!/bin/bash
while true
do
echo Hello Embedfire >> /tmp/hello.log
sleep 3
done
|
将以上目录打包构建成deb文件并在板子上使用dpkg命令安装即可。 重启后使用``systemctl status hello`` 查看服务相关状态如下。
1 2 3 4 5 6 7 8 9 10 11 12 | root@npi:~# systemctl status hello
● hello.service - hello daemon
Loaded: loaded (/etc/systemd/system/hello.service; enabled; vendor preset: en
Active: active (running) since Mon 2021-05-31 15:52:32 CST; 56s ago
Main PID: 340 (hello_deb.sh)
Tasks: 2 (limit: 385)
Memory: 408.0K
CGroup: /system.slice/hello.service
├─340 /bin/bash /opt/hello_deb/hello_deb.sh
└─503 sleep 3
May 31 15:52:32 npi systemd[1]: Started hello daemon.
|
也可通过查看/tmp/hello.log文件查看程序是否正确执行。