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
26
27
28
29
30
31
32
33
34
35
cat@lubancat:~$ 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                             Architecture Description
+++-========================================-===================================-============-===============================================================================
ii  acpi-support-base                        0.142-8                             all          scripts for handling base ACPI events such as the power button
ii  acpid                                    1:2.0.31-1                          arm64        Advanced Configuration and Power Interface event daemon
ii  adduser                                  3.118                               all          add and remove users and groups
ii  adwaita-icon-theme                       3.30.1-1                            all          default icon theme of GNOME
ii  alsa-utils                               1.1.8-2                             arm64        Utilities for configuring and using ALSA
ii  anacron                                  2.3-28                              arm64        cron-like program that doesn't go by time
ii  apt                                      1.8.2.3                             arm64        commandline package manager
ii  apt-transport-https                      1.8.2.3                             all          transitional package for https support
ii  apt-utils                                1.8.2.3                             arm64        package management related utility programs
ii  aspell                                   0.60.7~20110707-6+deb10u1           arm64        GNU Aspell spell-checker
ii  aspell-en                                2018.04.16-0-1                      all          English dictionary for GNU Aspell
ii  base-files                               10.3+deb10u13                       arm64        Debian base system miscellaneous files
ii  base-passwd                              3.5.46                              arm64        Debian base system master password and group files
ii  bash                                     5.0-4                               arm64        GNU Bourne Again SHell
ii  binfmt-support                           2.2.0-2                             arm64        Support for extra binary formats
ii  blueman                                  2.0.8-1+deb10u1                     arm64        Graphical bluetooth manager
ii  bluez                                    5.50-1.2~deb10u2                    arm64        Bluetooth tools and daemons
ii  bluez-obexd                              5.50-1.2~deb10u2                    arm64        bluez obex daemon
ii  bsdmainutils                             11.1.2+b1                           arm64        collection of more utilities from FreeBSD
ii  bsdutils                                 1:2.33.1-0.1                        arm64        basic utilities from 4.4BSD-Lite
ii  bubblewrap                               0.3.1-4                             arm64        setuid wrapper for unprivileged chroot and namespace manipulation
ii  busybox                                  1:1.30.1-4                          arm64        Tiny utilities for small and embedded systems
ii  bzip2                                    1.0.6-9.2~deb10u2                   arm64        high-quality block-sorting file compressor - utilities
ii  ca-certificates                          20200601~deb10u2                    all          Common CA certificates
ii  camera-engine-rkaiq                      2.0x60.1                            arm64        3A libraries match Rockchip rkisp v21(rk356x).
ii  can-utils                                2018.02.0-1                         arm64        SocketCAN userspace utilities and tools
ii  cheese                                   3.31.90-1                           arm64        tool to take pictures and videos from your webcam
ii  cheese-common                            3.31.90-1                           all          Common files for the Cheese tool to take pictures and videos
lines 1-33

上面是LubanCat板卡Debian镜像所安装的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文件可执行权限,postinst和postrm的权限必须>=0555且<=0775。

其中control文件所包含信息如下:

hello_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

注解

control文件的末尾需添加一个空行,否则会报错“缺失结尾的换行符”

若以后想升级这个deb包,可以修改该包的版本号Version,值得注意的是Architecture, 前面我们也有讲到,就是该deb包所支持的处理器架构,因为最终要将该deb包安装到arm64处理器的板卡上, 所以我们应该在Architecture中填入arm64属性,大家可根据自己的需求做相应修改即可, 如果不知道你的处理器架可以通过dpkg -l命令来查看已安装的deb包持支的架构, 或者输入lscpu查看处理器信息,aarch64就是arm64架构。若想支持所有架构,可以填入all属性, 如果Architecture属性与当前处理器架构属性不匹配的话,deb包将无法成功安装, 且control的属性信息必须以字母或者数字开头,不然可能导致打包出错。

postinst文件包含信息如下:

hello_deb/DEBIAN/postinst
1
2
3
4
5
#!/bin/bash

if [ "$1" = "upgrade" ] || [ "$1" = "install" ];then
    echo "hello_deb installing"
fi

当安装了该deb包以后,系统会默认执行postinst脚本, 通常我们利用该脚本来搭建一些为软件执行的环境(如创建目录、修改权限等), 值得注意的是该文件需具有可执行权限。 这里写的比较简单,判断第一个参数,仅供参考。

postrm文件包含信息如下:

hello_deb/DEBIAN/postrm
1
2
3
4
5
6
7
#!/bin/bash

if [ "$1" = "upgrade" ] ; then
    echo "upgrade"
elif [ "$1" = "remove" ] || [ "$1" = "purge" ] ; then
    echo "remove"
fi

当卸载了该deb包以后,系统会默认执行postrm脚本,通常我们利用该脚本来清理环境, 值得注意的是该文件具有可执行权限。 这里写的比较简单,判断第一个参数,仅供参考。

最后我们来看下真正的程序主体,为了简单起见,此处以一个简单的脚本为例。

hello_deb/opt/hello_deb/hello_deb.sh
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
jiawen@dev120:~/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'

制作好自己的deb包后我们需要验证一下是否真的制作成功, 可以如下命令查看已制作的deb包文件内容:

1
2
3
4
5
6
7
8
#命令
dpkg -c  hello_deb_1.0.0_arm64.deb

#打印信息
drwxrwxr-x jiawen/jiawen     0 2022-10-12 09:27 ./
drwxrwxr-x jiawen/jiawen     0 2022-10-12 09:28 ./opt/
drwxrwxr-x jiawen/jiawen     0 2022-10-12 09:28 ./opt/hello_deb/
-rwxrwxrwx jiawen/jiawen    59 2022-10-12 09:41 ./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=496 bytes.
    190 字节,    9 行      control
    100 字节,    4 行   *  postinst             #!/bin/bash
    138 字节,    7 行   *  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包拷贝到LubanCat板卡的文件系统下, 输入“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
cat@lubancat:~$ sudo dpkg -i hello_deb_1.0.0_arm64.deb
Selecting previously unselected package hello-deb.
(Reading database ... 74783 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) ...
cat@lubancat:~$ 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
cat@lubancat:~$ dpkg -l | grep hello-deb
ii  hello-deb          1.0.0           arm64        deb test

验证安装完成之后查看开发板/opt/hello_deb目录下是否存在hello_deb.sh文件。

1
2
3
4
cat@lubancat:~$ ls /opt/
hello_deb
cat@lubancat:~$ ls /opt/hello_deb/
hello_deb.sh

执行看看效果

1
2
3
cat@lubancat:~$ /opt/hello_deb/hello_deb.sh
Hello deb!
This is a test script!!!

到此,制作deb包的基本流程已介绍完毕。

2.4. 从根据已有deb包修改内容

下面介绍下如何修改已有的deb包,以刚刚创建的deb包为例,直接在LubanCat板卡上修改。

在LubanCat板卡上安装工具及依赖:

sudo apt-get install build-essential debhelper make autoconf automake dpkg-dev fakeroot pbuilder gnupg

新建一个update_deb目录,使用 dpkg -X 命令将deb包解压到update_deb目录中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
cat@lubancat:~$ ls
Desktop    Downloads  Pictures  Templates  hello_deb_1.0.0_arm64.deb
Documents  Music      Public    Videos
cat@lubancat:~$ mkdir update_deb
cat@lubancat:~$ sudo dpkg -X  hello_deb_1.0.0_arm64.deb  update_deb/
./
./opt/
./opt/hello_deb/
./opt/hello_deb/hello_deb.sh
cat@lubancat:~$

进入update_deb目录下可看到并没DEBIAN相关目录,在update_deb目录下使用 dpkg -e 解压出控制文件相关信息。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
cat@lubancat:~/update_deb$ ls
opt
cat@lubancat:~/update_deb$ sudo dpkg -e ../hello_deb_1.0.0_arm64.deb
cat@lubancat:~/update_deb$ ls -al
total 16
drwxrwxr-x  4 1001 1001 4096 Oct 12 13:37 .
drwxr-xr-x 15 cat  cat  4096 Oct 12 13:35 ..
drwxr-xr-x  2 root root 4096 Oct 12 09:28 DEBIAN
drwxrwxr-x  3 1001 1001 4096 Oct 12 09:28 opt

cat@lubancat:~/update_deb$ tree
.
|-- DEBIAN
|   |-- control
|   |-- postinst
|   `-- postrm
`-- opt
    `-- hello_deb
        `-- hello_deb.sh

3 directories, 4 files

此时就可以对程序主体进行修改了,我们在opt/hello_deb/hello_deb.sh下添加一句打印消息, 如下所示

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下的版本信息,将Version修改为1.0.1

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
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
cat@lubancat:~/update_deb$ sudo dpkg-deb -b ../update_deb ../hello_deb_1.0.1_arm64.deb
dpkg-deb: building package 'hello-deb' in '../hello_deb_1.0.1_arm64.deb'.

cat@lubancat:~$ sudo dpkg -i hello_deb_1.0.1_arm64.deb
(Reading database ... 103608 files and directories currently installed.)
Preparing to unpack hello_deb_1.0.1_arm64.deb ...
Unpacking hello-deb (1.0.1) over (1.0.0) ...
upgrade
Setting up hello-deb (1.0.1) ...

cat@lubancat:~$ /opt/hello_deb/hello_deb.sh
Hello deb!
This is a test script!!!
update deb!

2.5. 简单实例:通过安装deb包创建开机自启服务

通过安装deb包在LubanCat板卡上实现程序开机自启,在实际项目上的应用极为普遍, 下面通过一个简单的实例介绍相关如何使用创建开机自动的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文件内容如下所示

DEBIAN/control
1
2
3
4
5
6
7
8
9
Package: hello-deb
Version: 1.0.2
Section: free
Priority: optional
Essential: no
Architecture: arm64
Maintainer: embedfire <embedfire@embedfire.com>
Provides: hell_deb
Description: deb test

DEBIAN/postinst文件内容如下所示,脚本的内容很简单只是使能了hello相关服务并启动它。

DEBIAN/postinst
1
2
3
4
5
6
7
#!/bin/bash

if [ "$1" = "upgrade" ] || [ "$1" = "install" ];then
    echo "hello_deb installing"
    systemctl enable hello
    systemctl start hello
fi

DEBIAN/postinst文件内容如下所示,当卸载程序时,关闭hello相关服务。

DEBIAN/postrm
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服务内容如下,重点在于第六行,指定需要执行的程序。

/etc/systemd/system/hello.service
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[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。

/opt/hello_deb/hello_deb.sh
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
13
14
15
16
17
root@lubancat:~# systemctl status hello
● hello.service - hello daemon
    Loaded: loaded (/etc/systemd/system/hello.service; enabled; vendor preset:>
    Active: active (running) since Wed 2022-10-12 13:54:55 CST; 12s ago
  Main PID: 372 (hello_deb.sh)
    Memory: 2.5M
    CGroup: /system.slice/hello.service
            ├─372 /bin/bash /opt/hello_deb/hello_deb.sh
            └─817 sleep 3
lines 1-8/8 (END)

root@lubancat:~# cat /tmp/hello.log
Hello Embedfire
Hello Embedfire
Hello Embedfire
Hello Embedfire
Hello Embedfire

也可通过查看/tmp/hello.log文件查看程序是否正确执行。