-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.xml
More file actions
3843 lines (3789 loc) · 341 KB
/
index.xml
File metadata and controls
3843 lines (3789 loc) · 341 KB
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>永远null的成元</title>
<link>https://DSJZS.github.io/</link>
<description>Recent content on 永远null的成元</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<copyright>永远null的成元</copyright><atom:link href="https://DSJZS.github.io/index.xml" rel="self" type="application/rss+xml" /><item>
<title>Linux开发学习记录(4):如何愉快(?)地交叉编译</title>
<link>https://DSJZS.github.io/p/linux%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%954%E5%A6%82%E4%BD%95%E6%84%89%E5%BF%AB%E5%9C%B0%E4%BA%A4%E5%8F%89%E7%BC%96%E8%AF%91/</link>
<pubDate>Tue, 03 Mar 2026 13:32:00 +0800</pubDate>
<guid>https://DSJZS.github.io/p/linux%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%954%E5%A6%82%E4%BD%95%E6%84%89%E5%BF%AB%E5%9C%B0%E4%BA%A4%E5%8F%89%E7%BC%96%E8%AF%91/</guid>
<description><h2 id="前言">前言
</h2><p>随着不断地学习(<del>败家</del>),现在我手里积攒了许多不同体系结构的设备,比如 x86_64、ARM、aarch64 等等,也是花了我不少的钱💸。</p>
<p>平常我主要是在自己的 x86_64 电脑上写 C/C++ 代码,然后进行编译和测试,测试没问题之后,便会将程序下载到其它架构的机器上。但C/C++是&quot;一次编写处处编译&quot;的语言,不同架构的机器要对用对应架构的编译工具链来完成编译,如果你用系统自带的 <code>gcc</code> 编译你的代码,那么大概率编译出来的程序只能在当前架构的机器上运行(对我来说就是x86_64)。</p>
<p>为了让编译出来的程序能在其他架构的机器上跑起来,得用对应架构的交叉编译工具链,或者干脆直接把代码丢到对应架构的机器上,它自己编译出来的程序自己大概率能用。</p>
<blockquote>
<p>交叉编译,简单说就是在一种架构的机器上编译出给另一种架构用的程序。</p>
</blockquote>
<p>这篇文章就用来记录我折腾过程中发现的一些交叉编译方法,目前摸索到的有以下两种:</p>
<ul>
<li><a class="link" href="#%e4%ba%a4%e5%8f%89%e7%bc%96%e8%af%91%e5%b7%a5%e5%85%b7%e9%93%be" >交叉编译工具链</a></li>
<li><a class="link" href="#docker%e8%bf%90%e8%a1%8c%e9%9d%9e%e6%9c%ac%e6%9c%ba%e6%9e%b6%e6%9e%84%e7%bc%96%e8%af%91" >Docker运行非本机架构编译</a>(说实话这种方式严格来讲并非交叉编译的范畴,不过也能实现我们的目标)</li>
</ul>
<h2 id="本文的情景设定">本文的情景设定
</h2><p>假设你有一个朋友叫李华,你和他生活在一个只有 Linux 系统的世界。</p>
<p>某天,李华的C语言课程老师要求李华写一个经典的 hello world 程序作为第一节课的课后作业。</p>
<p>于是李华<del>照着PTT</del>创建了 ~/hello.c ,并往其中写入了如下的内容:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;hello world</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>并使用 <code>gcc</code> 进行编译,得到了正确输出 hello world 的可执行文件 hello,如下:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ gcc --static -o hello hello.c
</span></span><span class="line"><span class="cl">~$ ./hello
</span></span><span class="line"><span class="cl">hello world
</span></span></code></pre></td></tr></table>
</div>
</div><p>完全没问题!于是李华按照要求,把可执行文件 hello 发到了老师的邮箱(或者QQ、微信等平台)。</p>
<p>过了一会儿,李华的老师给他发了一张截图,说有BUG(<del>BIG</del>),他点开来一看,发现了如下的报错文本:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~/作业/李华boy$ ./hello
</span></span><span class="line"><span class="cl">可执行文件格式错误: ./hello
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 当然也可能是找不到动态库的报错,反正李华老师的电脑大概率运行不了</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>然后李华就傻了,这是为啥啊?我电脑上运行的好好的。</p>
<p>原来老师的电脑是 aarch64 架构的,和李华的 x86_64 架构不同,李华用自带的 <code>gcc</code> 进行编译后,编译出来的可执行文件格式不对。</p>
<p>请你帮助李华正确的完成编译,将格式正确的可执行文件交给他。</p>
<h2 id="交叉编译工具链">交叉编译工具链
</h2><p>这个是最常见的一种办法,你可以下载对应架构对应的交叉编译工具链,用这个交叉编译工具链里面的<code>gcc</code>来编译程序。</p>
<p>通过<a class="link" href="#%e6%9c%ac%e6%96%87%e7%9a%84%e6%83%85%e6%99%af%e8%ae%be%e5%ae%9a" >情景设定</a>可知李华老师的电脑架构为 aarch64,操作系统为 Linux,那么只要下载 aarch64-linux 交叉编译工具链就行了!</p>
<p>对应的工具链可以从 <a class="link" href="https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads" target="_blank" rel="noopener"
>Arm GNU Toolchain Downloads</a> 网站之中获取,如下图:</p>
<p><img src="https://DSJZS.github.io/p/linux%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%954%E5%A6%82%E4%BD%95%E6%84%89%E5%BF%AB%E5%9C%B0%E4%BA%A4%E5%8F%89%E7%BC%96%E8%AF%91/%E5%B7%A5%E5%85%B7%E9%93%BE%E4%B8%8B%E8%BD%BD%E6%BC%94%E7%A4%BA.png"
width="1032"
height="888"
srcset="https://DSJZS.github.io/p/linux%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%954%E5%A6%82%E4%BD%95%E6%84%89%E5%BF%AB%E5%9C%B0%E4%BA%A4%E5%8F%89%E7%BC%96%E8%AF%91/%E5%B7%A5%E5%85%B7%E9%93%BE%E4%B8%8B%E8%BD%BD%E6%BC%94%E7%A4%BA_hu_89f52853e3f7b42a.png 480w, https://DSJZS.github.io/p/linux%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%954%E5%A6%82%E4%BD%95%E6%84%89%E5%BF%AB%E5%9C%B0%E4%BA%A4%E5%8F%89%E7%BC%96%E8%AF%91/%E5%B7%A5%E5%85%B7%E9%93%BE%E4%B8%8B%E8%BD%BD%E6%BC%94%E7%A4%BA_hu_db84dd1f6e2a4e63.png 1024w"
loading="lazy"
alt="工具链下载演示"
class="gallery-image"
data-flex-grow="116"
data-flex-basis="278px"
></p>
<p>下载图中所示的 arm-gnu-toolchain-15.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz 解压并放到对应的目录下,具体命令如下:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ wget https://developer.arm.com/-/media/Files/downloads/gnu/15.2.rel1/binrel/arm-gnu-toolchain-15.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
</span></span><span class="line"><span class="cl">~$ tar -Jxvf arm-gnu-toolchain-15.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
</span></span><span class="line"><span class="cl">~$ mkdir -p /usr/local/aarch64
</span></span><span class="line"><span class="cl">~$ sudo mv arm-gnu-toolchain-15.2.rel1-x86_64-aarch64-none-linux-gnu /usr/local/aarch64/
</span></span><span class="line"><span class="cl">~$ <span class="nb">echo</span> <span class="s1">&#39;export PATH=$PATH:/usr/local/aarch64/arm-gnu-toolchain-15.2.rel1-x86_64-aarch64-none-linux-gnu/bin&#39;</span> &gt;&gt; ~/.bashrc
</span></span></code></pre></td></tr></table>
</div>
</div><p>上面的演示先是用 <code>wget</code> 下载了压缩包(当然,你可以直接在浏览器中下载),然后解压并将解压出来的文件全部移动到 <code>/usr/local/aarch64/</code> ,最后在 bash shell 的初始化文件中给 PATH 环境变量添加对应的路径使Linux能直接找到我们接下来要用到的工具(如果你用的不是 bash ,比如 zsh,请自行改为放到对应的 shell 初始化文件中)。</p>
<p>最后你便可以使用交叉编译工具对李华的代码进行编译,得到能在李华老师电脑上运行的程序了,如下:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ aarch64-none-linux-gnu-gcc --static -o hello_aarch64 hello.c
</span></span></code></pre></td></tr></table>
</div>
</div><p>这里得到的 hello_aarch64 在李华老师的电脑上便能正常执行,完成任务!<br>
( 这里使用 <code>--static</code> 是因为李华和他老师电脑上的 glibc 版本可能不同 )</p>
<h2 id="docker运行非本机架构编译">Docker运行非本机架构编译
</h2><p>说实话这种方式严格来讲并非交叉编译的范畴,不过也能实现我们的目标。</p>
<p>这个方法本质上就是根据对应架构和系统选择相应的Docker镜像创建容器,然后进入到容器之中进行编译。</p>
<p>通过<a class="link" href="#%e6%9c%ac%e6%96%87%e7%9a%84%e6%83%85%e6%99%af%e8%ae%be%e5%ae%9a" >情景设定</a>可知李华老师的电脑架构为 aarch64,操作系统为 Linux,假设李华老师的电脑是 Ubuntu 24.04 ,我们按照接下来的方法即可得到我们想要的可执行程序。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ mkdir -p ./dir <span class="o">&amp;&amp;</span> mv helle.c ./dir/
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 安装所有架构的模拟器</span>
</span></span><span class="line"><span class="cl">~$ sudo docker run --privileged --rm tonistiigi/binfmt --install all
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 创建一次性容器</span>
</span></span><span class="line"><span class="cl">~$ sudo docker run -it --rm --platform linux/arm64 -v ./dir:/app ubuntu:20.04
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 编译</span>
</span></span><span class="line"><span class="cl">/# <span class="nb">cd</span> app
</span></span><span class="line"><span class="cl">/app# apt update <span class="o">&amp;&amp;</span> apt install build-essential
</span></span><span class="line"><span class="cl">/app# gcc -o hello hello.c
</span></span><span class="line"><span class="cl">/app# <span class="nb">exit</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 此时进入 dir 文件,即可获取对应架构的可执行程序</span>
</span></span><span class="line"><span class="cl">~$ <span class="nb">cd</span> dir
</span></span><span class="line"><span class="cl">~/dir$ ls hello
</span></span><span class="line"><span class="cl">hello
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="参考">参考
</h2><h3 id="开源项目">开源项目
</h3><p><a class="link" href="https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads" target="_blank" rel="noopener"
>Arm GNU Toolchain Downloads</a><br>
<a class="link" href="https://hub.docker.com/r/tonistiigi/binfmt" target="_blank" rel="noopener"
>tonistiigi/binfmt</a></p>
<h3 id="自媒体">自媒体
</h3><p><a class="link" href="https://blog.hentioe.dev/posts/docker-run-non-native-architecture-images.html" target="_blank" rel="noopener"
>让 Docker 运行非本机架构的镜像(binfmt_misc)</a><br>
<a class="link" href="https://www.bilibili.com/video/BV1hqRhYnEhA/?spm_id_from=333.1391.0.0&amp;vd_source=9b2ee795ef170df3280fc7223c9f92b8" target="_blank" rel="noopener"
>交叉编译?狗都不用,还是玩docker容器吧</a></p>
</description>
</item>
<item>
<title>Linux开发学习记录(3):如何愉快(?)地使用Makefile</title>
<link>https://DSJZS.github.io/p/linux%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%953%E5%A6%82%E4%BD%95%E6%84%89%E5%BF%AB%E5%9C%B0%E4%BD%BF%E7%94%A8makefile/</link>
<pubDate>Thu, 19 Feb 2026 11:41:51 +0800</pubDate>
<guid>https://DSJZS.github.io/p/linux%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%953%E5%A6%82%E4%BD%95%E6%84%89%E5%BF%AB%E5%9C%B0%E4%BD%BF%E7%94%A8makefile/</guid>
<description><h2 id="参考">参考
</h2><ul>
<li><a class="link" href="https://www.bilibili.com/video/BV1Bv4y1J7QT/?share_source=copy_web&amp;vd_source=001d8202e6bdc4ef4666a69dde3b47ff" target="_blank" rel="noopener"
>无限十三年/从零开始学Makefile</a> &amp; <a class="link" href="https://gitee.com/unlimited13/cpp/tree/master/Make" target="_blank" rel="noopener"
>无限十三年/CPP/Make</a></li>
<li><a class="link" href="https://liaoxuefeng.com/books/makefile/introduction/index.html" target="_blank" rel="noopener"
>廖雪峰/Makefile教程</a></li>
<li><a class="link" href="https://www.gnu.org/software/make/manual/" target="_blank" rel="noopener"
>GNU Make Manual</a></li>
</ul>
</description>
</item>
<item>
<title>Linux开发学习记录(2):如何愉快(?)地使用Debian系基础包管理工具</title>
<link>https://DSJZS.github.io/p/linux%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%952%E5%A6%82%E4%BD%95%E6%84%89%E5%BF%AB%E5%9C%B0%E4%BD%BF%E7%94%A8debian%E7%B3%BB%E5%9F%BA%E7%A1%80%E5%8C%85%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7/</link>
<pubDate>Tue, 17 Feb 2026 14:04:55 +0800</pubDate>
<guid>https://DSJZS.github.io/p/linux%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%952%E5%A6%82%E4%BD%95%E6%84%89%E5%BF%AB%E5%9C%B0%E4%BD%BF%E7%94%A8debian%E7%B3%BB%E5%9F%BA%E7%A1%80%E5%8C%85%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7/</guid>
<description><h2 id="前言">前言
</h2><p>This blog does have Super Cow Powers.<br>
本文会简略地介绍以下内容:</p>
<ul>
<li><a class="link" href="#deb" >.deb 软件包</a></li>
<li><a class="link" href="#dpkg" >dpkg</a></li>
<li><a class="link" href="#dpkg-deb" >dpkg-deb</a></li>
<li><a class="link" href="#dpkg-query" >dpkg-query</a></li>
<li><a class="link" href="#apt" >apt</a></li>
<li><a class="link" href="#aptitude" >aptitude</a></li>
</ul>
<p>如果想了解详细的内容,请自行阅读对应的资料。</p>
<h2 id="deb">.deb
</h2><p>.deb 是 Debian 及其衍生系统(如Ubuntu)的软件包格式,<strong>本质上是一个 ar 归档文件,包含软件的二进制文件、配置文件、依赖信息等</strong>。<br>
通过 <code>ar</code> 命令可以查看其内部结构( code.deb 的获取方式见<a class="link" href="#%e6%bc%94%e7%a4%ba%e7%94%a8%e7%9a%84-deb-%e5%8c%85" >备注</a> ):</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ ar t code.deb
</span></span><span class="line"><span class="cl">debian-binary
</span></span><span class="line"><span class="cl">control.tar.xz
</span></span><span class="line"><span class="cl">data.tar.xz
</span></span><span class="line"><span class="cl">_gpgorigin
</span></span></code></pre></td></tr></table>
</div>
</div><p>典型的 .deb 包包含 3 部分:</p>
<ul>
<li>debian-binary:文本文件,记录 deb 格式版本(通常为 2.0)</li>
<li>control.tar.gz:压缩包,包含软件包的元数据和控制脚本,核心文件为 control(依赖、版本等信息)</li>
<li>data.tar.xz/gz:压缩包,包含软件的实际文件(二进制、配置、文档等),解压后会安装到系统对应路径(如 /usr/bin/、/etc/)
上面演示中出现的 <code>_gpgorigin</code> 并不是 .deb 包常见的内容,用于验证包的完整性和真实性。</li>
</ul>
<h2 id="dpkg">dpkg
</h2><h3 id="工具介绍">工具介绍
</h3><p>dpkg 是 Debian 系 Linux 中最基础的包管理工具,全称为 <em>Debian Package Manager</em> 。<br>
它的主要功能如下:</p>
<ul>
<li>直接操作 .deb 格式的软件包(安装、卸载、查询、验证);</li>
<li>维护系统软件包数据库(记录已安装包的状态、文件列表等);</li>
<li>处理软件包安装过程中的文件解压、配置脚本执行等底层操作。</li>
</ul>
<p>它的上游工具是 <a class="link" href="#apt" >apt</a> 和 <a class="link" href="#aptitude" >aptitude</a>,它的下游工具是 <a class="link" href="#dpkg-deb" >dpkg-deb</a> 和 <a class="link" href="#dpkg-query" >dpkg-query</a>。<br>
也就是说 dpkg 是 dpkg-deb 和 dpkg-query 的前端工具,与此同时 apt 和 aptitude 是 dpkg 的前端工具。</p>
<p>如果你查询 dpkg、dpkg-deb 和 dpkg-query 的手册,会发现 dpkg-deb 和 dpkg-query 有的选项,dpkg 基本上也有。<strong>事实上 dpkg 工具作为一个“前端”,可以识别并调用 dpkg-query 和 dpkg-deb 的大部分常用选项,但它并不支持这两个工具的所有选项,尤其是那些用于精细化控制的选项</strong>,当他发现用户调用的选项是其后端的选项,其会传递参数给后端并将控制权交给后端执行对应的选项。</p>
<blockquote>
<p>注意:dpkg 是底层工具,不负责自动解决依赖关系,并且其假定用户已经将 .deb 软件包下载到本地或者能以 URL 的形式提供。处理依赖关系或者自动下载等功能需要用到它的上游工具(实际上日常使用也推荐使用它的上游工具)。详情见<a class="link" href="#%e5%ae%89%e8%a3%85%e8%bd%af%e4%bb%b6%e5%8c%85" >dpkg 安装软件包</a>小节、<a class="link" href="#apt" > apt 的介绍</a>小节和<a class="link" href="#aptitude" > aptitude 的介绍</a>小节。</p>
</blockquote>
<p>可以参考<a class="link" href="#debian%e7%b3%bb%e7%bb%9f%e5%8c%85%e7%ae%a1%e7%90%86%e5%b7%a5%e5%85%b7%e6%80%9d%e7%bb%b4%e5%af%bc%e5%9b%be" >Debian系统包管理工具思维导图</a>理解各个工具之间的关系。</p>
<h3 id="主要功能">主要功能
</h3><h4 id="安装软件包">安装软件包
</h4><ul>
<li>选项:<code>-i, --install package-file...</code><br>
举例,如下:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ sudo dpkg -i code.deb
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>注意:dpkg 安装 deb 软件包时,会先解压文件安装,再检查依赖是否完整,如果依赖不完整,那么 dpkg 还是会认为 deb 软件包安装成功,并提醒用户自行下载依赖并安装</strong>。
如果发现依赖缺失,可以利用 apt 等高级工具安装依赖,比如使用命令 <code>apt install -f</code> 尝试修复。</p>
<p><strong>即使是本地 deb 包,也建议直接使用apt等高级工具来安装,这样便于处理依赖关系</strong>,更多见<a class="link" href="#apt" > apt 章节</a>。</p>
<h4 id="卸载软件包">卸载软件包
</h4><ul>
<li>选项:<code>-r, --remove package...|-a|--pending</code><br>
该选项用于卸载软件包,但<strong>保留</strong>配置文件。<br>
如果提供 <code>-a</code> 或 <code>--pending</code> 而不是软件包名称,则将移除文件 <code>/var/lib/dpkg/status</code> 中标记为要移除的所有已解压软件包。<br>
举例,如下:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ sudo dpkg -r code
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>选项:<code>-P, --purge package...|-a|--pending</code><br>
该选项用于卸载软件包,并<strong>删除</strong>配置文件。<br>
如果提供 <code>-a</code> 或 <code>--pending</code> 而不是软件包名称,则将移除文件 <code>/var/lib/dpkg/status</code> 中标记为要移除的所有已解压软件包。<br>
举例,如下:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ sudo dpkg -P code
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="修复损坏的软件包">修复损坏的软件包
</h4><ul>
<li>选项:<code>--configure package...|-a|--pending</code><br>
该选项用于配置已解压但尚未配置的软件包,如果提供 <code>-a</code> 或 <code>--pending</code> 而不是软件包名称,则将配置所有已解压但未配置的软件包。<br>
当软件包安装/配置过程中断(如断电、手动终止),可能导致“半配置”状态,即文件已经解压,但是软件包自带的配置脚本(如 postinst)没有完全运行,导致配置&quot;卡在一半&quot;了,可以使用该选项处理。</li>
</ul>
<h3 id="调用后端工具">调用后端工具
</h3><p>如<a class="link" href="#%e5%b7%a5%e5%85%b7%e4%bb%8b%e7%bb%8d" > dpkg 的工具介绍</a>中所说的一样,dpkg 可以直接使用其后端工具的大部分选项。<br>
举例:如下:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ dpkg-query -l code <span class="p">|</span> tail -3
</span></span><span class="line"><span class="cl"><span class="o">||</span>/ 名称 版本 体系结构 描述
</span></span><span class="line"><span class="cl">+++-<span class="o">==============</span>-<span class="o">==================</span>-<span class="o">============</span>-<span class="o">=================================</span>
</span></span><span class="line"><span class="cl">ii code 1.104.1-1758154125 amd64 Code editing. Redefined.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">~$ dpkg -l code <span class="p">|</span> tail -3
</span></span><span class="line"><span class="cl"><span class="o">||</span>/ 名称 版本 体系结构 描述
</span></span><span class="line"><span class="cl">+++-<span class="o">==============</span>-<span class="o">==================</span>-<span class="o">============</span>-<span class="o">=================================</span>
</span></span><span class="line"><span class="cl">ii code 1.104.1-1758154125 amd64 Code editing. Redefined.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 可以看到 dpkg-query 的选项 -l 也可以通过 dkpg 直接使用(dpkg会自动识别并传递参数给 dpkg-query )</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>详情见<a class="link" href="#%e4%b8%bb%e8%a6%81%e5%8a%9f%e8%83%bd-1" > dpkg-deb 的功能介绍</a>与<a class="link" href="#%e4%b8%bb%e8%a6%81%e5%8a%9f%e8%83%bd-2" > dpkg-query 的功能介绍</a>。</p>
<h2 id="dpkg-deb">dpkg-deb
</h2><h3 id="工具介绍-1">工具介绍
</h3><p>dpkg-deb 用于打包、解包 Debian 软件包(.deb)以及提供相关信息。</p>
<p>可以参考<a class="link" href="#debian%e7%b3%bb%e7%bb%9f%e5%8c%85%e7%ae%a1%e7%90%86%e5%b7%a5%e5%85%b7%e6%80%9d%e7%bb%b4%e5%af%bc%e5%9b%be" >Debian系统包管理工具思维导图</a>理解各个工具之间的关系。</p>
<h3 id="主要功能-1">主要功能
</h3><h4 id="查询-deb-软件包的信息">查询 .deb 软件包的信息
</h4><ul>
<li>选项:<code>-I, --info archive [control-file-name...]</code><br>
该选项用于显示 .deb 软件包的信息。<br>
举例,如下:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ dpkg-deb -I code.deb
</span></span><span class="line"><span class="cl"> 新格式的 Debian 软件包,格式版本 2.0。
</span></span><span class="line"><span class="cl"> 大小 <span class="m">116522198</span> 字节:主控包<span class="o">=</span><span class="m">3292</span> 字节。
</span></span><span class="line"><span class="cl"> <span class="m">1439</span> bytes, <span class="m">18</span> lines control
</span></span><span class="line"><span class="cl"> <span class="m">4461</span> 字节, <span class="m">131</span> 行 * postinst <span class="c1">#!/usr/bin/env</span>
</span></span><span class="line"><span class="cl"> <span class="m">920</span> 字节, <span class="m">34</span> 行 * postrm <span class="c1">#!/bin/bash</span>
</span></span><span class="line"><span class="cl"> <span class="m">274</span> 字节, <span class="m">6</span> 行 * prerm <span class="c1">#!/usr/bin/env</span>
</span></span><span class="line"><span class="cl"> <span class="m">234</span> bytes, <span class="m">6</span> lines templates
</span></span><span class="line"><span class="cl"> Package: code
</span></span><span class="line"><span class="cl"> Version: 1.109.4-1771257466
</span></span><span class="line"><span class="cl"> Section: devel
</span></span><span class="line"><span class="cl"> Depends: ca-certificates, libasound2 <span class="o">(</span>&gt;<span class="o">=</span> 1.0.17<span class="o">)</span>, libatk-bridge2.0-0 <span class="o">(</span>&gt;<span class="o">=</span> 2.5.3<span class="o">)</span>, libatk1.0-0 <span class="o">(</span>&gt;<span class="o">=</span> 2.11.90<span class="o">)</span>, libatspi2.0-0 <span class="o">(</span>&gt;<span class="o">=</span> 2.9.90<span class="o">)</span>, libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.14<span class="o">)</span>, libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.16<span class="o">)</span>, libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.17<span class="o">)</span>, libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.2.5<span class="o">)</span>, libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.25<span class="o">)</span>, libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.28<span class="o">)</span>, libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.4<span class="o">)</span>, libcairo2 <span class="o">(</span>&gt;<span class="o">=</span> 1.6.0<span class="o">)</span>, libcurl3-gnutls <span class="p">|</span> libcurl3-nss <span class="p">|</span> libcurl4 <span class="p">|</span> libcurl3, libdbus-1-3 <span class="o">(</span>&gt;<span class="o">=</span> 1.9.14<span class="o">)</span>, libexpat1 <span class="o">(</span>&gt;<span class="o">=</span> 2.1~beta3<span class="o">)</span>, libgbm1 <span class="o">(</span>&gt;<span class="o">=</span> 17.1.0~rc2<span class="o">)</span>, libglib2.0-0 <span class="o">(</span>&gt;<span class="o">=</span> 2.39.4<span class="o">)</span>, libgtk-3-0 <span class="o">(</span>&gt;<span class="o">=</span> 3.9.10<span class="o">)</span>, libgtk-3-0 <span class="o">(</span>&gt;<span class="o">=</span> 3.9.10<span class="o">)</span> <span class="p">|</span> libgtk-4-1, libnspr4 <span class="o">(</span>&gt;<span class="o">=</span> 2:4.9-2~<span class="o">)</span>, libnss3 <span class="o">(</span>&gt;<span class="o">=</span> 2:3.30<span class="o">)</span>, libnss3 <span class="o">(</span>&gt;<span class="o">=</span> 3.26<span class="o">)</span>, libpango-1.0-0 <span class="o">(</span>&gt;<span class="o">=</span> 1.14.0<span class="o">)</span>, libudev1 <span class="o">(</span>&gt;<span class="o">=</span> 183<span class="o">)</span>, libx11-6, libx11-6 <span class="o">(</span>&gt;<span class="o">=</span> 2:1.4.99.1<span class="o">)</span>, libxcb1 <span class="o">(</span>&gt;<span class="o">=</span> 1.9.2<span class="o">)</span>, libxcomposite1 <span class="o">(</span>&gt;<span class="o">=</span> 1:0.4.4-1<span class="o">)</span>, libxdamage1 <span class="o">(</span>&gt;<span class="o">=</span> 1:1.1<span class="o">)</span>, libxext6, libxfixes3, libxkbcommon0 <span class="o">(</span>&gt;<span class="o">=</span> 0.5.0<span class="o">)</span>, libxkbfile1 <span class="o">(</span>&gt;<span class="o">=</span> 1:1.1.0<span class="o">)</span>, libxrandr2, xdg-utils <span class="o">(</span>&gt;<span class="o">=</span> 1.0.2<span class="o">)</span>
</span></span><span class="line"><span class="cl"> Recommends: libvulkan1
</span></span><span class="line"><span class="cl"> Priority: optional
</span></span><span class="line"><span class="cl"> Architecture: amd64
</span></span><span class="line"><span class="cl"> Maintainer: Microsoft Corporation &lt;vscode-linux@microsoft.com&gt;
</span></span><span class="line"><span class="cl"> Homepage: https://code.visualstudio.com/
</span></span><span class="line"><span class="cl"> Installed-Size: <span class="m">470414</span>
</span></span><span class="line"><span class="cl"> Provides: visual-studio-code
</span></span><span class="line"><span class="cl"> Conflicts: visual-studio-code
</span></span><span class="line"><span class="cl"> Replaces: visual-studio-code
</span></span><span class="line"><span class="cl"> Description: Code editing. Redefined.
</span></span><span class="line"><span class="cl"> Visual Studio Code is a new choice of tool that combines the simplicity of
</span></span><span class="line"><span class="cl"> a code editor with what developers need <span class="k">for</span> the core edit-build-debug cycle.
</span></span><span class="line"><span class="cl"> See https://code.visualstudio.com/docs/setup/linux <span class="k">for</span> installation
</span></span><span class="line"><span class="cl"> instructions and FAQ.
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="提取-deb-软件包中的文件">提取 .deb 软件包中的文件
</h4><ul>
<li>选项:<code>-x, --extract archive directory</code><br>
该选项用于将 .deb 软件包中的文件系统树(只有文件系统树,不包含DEBIAN目录)提取到指定的目录。<br>
<strong>注意,将包提取到根目录并不会导致正确的安装!请使用 dpkg 来安装包</strong>。<br>
举例,如下:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ dpkg-deb -x code.deb code
</span></span><span class="line"><span class="cl">~$ tree code <span class="p">|</span> head -10
</span></span><span class="line"><span class="cl">code
</span></span><span class="line"><span class="cl">└── usr
</span></span><span class="line"><span class="cl"> └── share
</span></span><span class="line"><span class="cl"> ├── appdata
</span></span><span class="line"><span class="cl"> │ └── code.appdata.xml
</span></span><span class="line"><span class="cl"> ├── applications
</span></span><span class="line"><span class="cl"> │ ├── code.desktop
</span></span><span class="line"><span class="cl"> │ └── code-url-handler.desktop
</span></span><span class="line"><span class="cl"> ├── bash-completion
</span></span><span class="line"><span class="cl"> │ └── completions
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>
<p>选项:<code>-X, --vextract archive directory</code><br>
类似上面的选项(-x),不过这个选项会显示解压的过程(每解压一个文件就显示该文件的路径)。<br>
<strong>注意,将包提取到根目录并不会导致正确的安装!请使用 dpkg 来安装包</strong>。</p>
</li>
<li>
<p>选项:<code>-R, --raw-extract archive directory</code>
类似上面的选项(-x),不过该选项用于会完整地提取出 .deb 包的所有内容(文件系统树和DEBIAN目录)。<br>
<strong>注意,将包提取到根目录并不会导致正确的安装!请使用 dpkg 来安装包</strong>。<br>
<strong>另外注意, dpkg 不能直接调用该选项</strong>。<br>
举例,如下:</p>
</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ dpkg-deb -R code.deb code
</span></span><span class="line"><span class="cl">~$ tree code <span class="p">|</span> head -10
</span></span><span class="line"><span class="cl">code
</span></span><span class="line"><span class="cl">├── DEBIAN
</span></span><span class="line"><span class="cl">│ ├── control
</span></span><span class="line"><span class="cl">│ ├── postinst
</span></span><span class="line"><span class="cl">│ ├── postrm
</span></span><span class="line"><span class="cl">│ ├── prerm
</span></span><span class="line"><span class="cl">│ └── templates
</span></span><span class="line"><span class="cl">└── usr
</span></span><span class="line"><span class="cl"> └── share
</span></span><span class="line"><span class="cl"> ├── appdata
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="创建新的-deb-软件包">创建新的 .deb 软件包
</h4><ul>
<li>选项:<code>-b, --build binary-directory [archive|directory]</code><br>
从存储在 <code>binary-directory</code> 中的文件系统树创建一个 debian 归档文件(即 .deb 软件包)。<br>
<code>binary-directory</code> 规定必须有一个 <code>DEBIAN</code> 子目录,其中包含控制信息文件,例如 <code>control</code>。<br>
构建时,<code>DEBIAN</code> 目录本身不会包含在最终包的根文件系统中,但其内容会成为包的控制数据。<br>
以下是 <code>DEBIAN</code> 目录中一些关键的特殊文件及其作用:
<table>
<thead>
<tr>
<th>文件名</th>
<th>必须?</th>
<th>作用</th>
</tr>
</thead>
<tbody>
<tr>
<td>control</td>
<td><strong>必需</strong></td>
<td><strong>这是核心文件,也是唯一绝对必需的文件</strong>。它定义了包的“身份信息”和“安装规则”,如包名、版本、架构、依赖关系、描述等。没有它,dpkg-deb 就不知道该如何描述这个包,构建会直接失败 。</td>
</tr>
<tr>
<td>preinst</td>
<td>可选</td>
<td>这是一个在软件包被解压之前执行的脚本。通常用于在实际安装前做一些准备工作,比如停止可能会冲突的服务,或者创建必要的用户和组 。</td>
</tr>
<tr>
<td>postinst</td>
<td>可选</td>
<td>这是最常用的维护者脚本之一,在软件包被解压并配置完成后执行。它用于完成安装后的设置工作,比如解压后创建符号链接、更新缓存、启动服务等 。</td>
</tr>
<tr>
<td>prerm</td>
<td>可选</td>
<td>在软件包被移除之前执行的脚本。常用于优雅地停止将要被移除的软件包所提供的服务 。</td>
</tr>
<tr>
<td>postrm</td>
<td>可选</td>
<td>在软件包被移除之后执行的脚本。用于执行最后的清理工作,比如删除用户、清理配置文件或日志文件 。</td>
</tr>
<tr>
<td>conffiles</td>
<td>可选</td>
<td>这个文件列出了该软件包中需要被作为配置文件对待的文件列表(每行一个)。dpkg 通过这个列表在升级时特别处理这些文件,以保留用户对配置文件的修改,而不会被新版本直接覆盖 。</td>
</tr>
<tr>
<td>shlibs</td>
<td>可选</td>
<td>这个文件记录了该软件包提供的共享库及其对应的依赖关系信息。它主要被 dpkg-shlibdeps 工具在构建时读取,用来为依赖该库的其他软件包自动生成准确的依赖关系 。</td>
</tr>
<tr>
<td>md5sums</td>
<td>可选</td>
<td>这个文件列出了包中所有文件的 MD5 校验和。dpkg 用它来验证软件包文件在安装后是否被篡改或损坏。通常由构建工具自动生成,但手动打包时也可以自己提供 。</td>
</tr>
<tr>
<td>triggers</td>
<td>可选</td>
<td>这个文件用于声明该软件包对某些事件的“触发”或“感兴趣”。这是一种更高级的机制,允许一个包的特定动作(如运行某个脚本)延迟到所有包处理完后再统一执行,以提高安装效率。</td>
</tr>
</tbody>
</table>
</li>
</ul>
<p>举例,如下:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ mkdir -p my-package/DEBIAN my-package/usr/local/bin
</span></span><span class="line"><span class="cl">~$ cat &gt; my-package/DEBIAN/control <span class="s">&lt;&lt; EOF
</span></span></span><span class="line"><span class="cl"><span class="s">Package: my-package
</span></span></span><span class="line"><span class="cl"><span class="s">Version: 1.0
</span></span></span><span class="line"><span class="cl"><span class="s">Architecture: amd64
</span></span></span><span class="line"><span class="cl"><span class="s">Maintainer: Your Name &lt;your@email.com&gt;
</span></span></span><span class="line"><span class="cl"><span class="s">Depends: libc6 (&gt;= 2.34)
</span></span></span><span class="line"><span class="cl"><span class="s">Description: A simple demo package
</span></span></span><span class="line"><span class="cl"><span class="s"> This is a minimal .deb package for testing.
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">~$ cat &gt; my-package/usr/local/bin/hello <span class="s">&lt;&lt; EOF
</span></span></span><span class="line"><span class="cl"><span class="s">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="s">echo &#34;Hello, dpkg!&#34;
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">~$ chmod u+x my-package/usr/local/bin/hello
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">~$ tree my-package
</span></span><span class="line"><span class="cl">my-package
</span></span><span class="line"><span class="cl">├── DEBIAN
</span></span><span class="line"><span class="cl">│ └── control
</span></span><span class="line"><span class="cl">└── usr
</span></span><span class="line"><span class="cl"> └── <span class="nb">local</span>
</span></span><span class="line"><span class="cl"> └── bin
</span></span><span class="line"><span class="cl"> └── hello
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">~$ dpkg-deb --build my-package
</span></span><span class="line"><span class="cl">dpkg-deb: 正在 <span class="s1">&#39;my-package.deb&#39;</span> 中构建软件包 <span class="s1">&#39;mypkg&#39;</span>。
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">~$ dpkg-deb -I my-package.deb
</span></span><span class="line"><span class="cl"> 新格式的 Debian 软件包,格式版本 2.0。
</span></span><span class="line"><span class="cl"> 大小 <span class="m">616</span> 字节:主控包<span class="o">=</span><span class="m">251</span> 字节。
</span></span><span class="line"><span class="cl"> <span class="m">192</span> bytes, <span class="m">7</span> lines control
</span></span><span class="line"><span class="cl"> Package: mypkg
</span></span><span class="line"><span class="cl"> Version: 1.0
</span></span><span class="line"><span class="cl"> Architecture: amd64
</span></span><span class="line"><span class="cl"> Maintainer: Your Name &lt;your@email.com&gt;
</span></span><span class="line"><span class="cl"> Depends: libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.34<span class="o">)</span>
</span></span><span class="line"><span class="cl"> Description: A simple demo package
</span></span><span class="line"><span class="cl"> This is a minimal .deb package <span class="k">for</span> testing.
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="dpkg-query">dpkg-query
</h2><h3 id="工具介绍-2">工具介绍
</h3><p>dpkg-query 是一个用于查询 dpkg 数据库的工具。</p>
<p>可以参考<a class="link" href="#debian%e7%b3%bb%e7%bb%9f%e5%8c%85%e7%ae%a1%e7%90%86%e5%b7%a5%e5%85%b7%e6%80%9d%e7%bb%b4%e5%af%bc%e5%9b%be" >Debian系统包管理工具思维导图</a>理解各个工具之间的关系。</p>
<h3 id="主要功能-2">主要功能
</h3><h4 id="查询-dpkg-数据库中已知软件包的信息">查询 dpkg 数据库中已知软件包的信息
</h4><h5 id="列出已知的软件包">列出已知的软件包
</h5><ul>
<li>选项:<code>-l, --list [package-name-pattern...].</code><br>
该选项用于列出 <strong>dpkg 数据库中已知的</strong>软件包。<br>
可以提供一个模式用于查找特定的软件包,或者不给出模式,会列出所有已知的软件包。<br>
举例,如下:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ dpkg-query -l code
</span></span><span class="line"><span class="cl">......
</span></span><span class="line"><span class="cl"><span class="o">||</span>/ 名称 版本 体系结构 描述
</span></span><span class="line"><span class="cl">+++-<span class="o">==============</span>-<span class="o">==================</span>-<span class="o">============</span>-<span class="o">=================================</span>
</span></span><span class="line"><span class="cl">ii code 1.104.1-1758154125 amd64 Code editing. Redefined.
</span></span></code></pre></td></tr></table>
</div>
</div><h5 id="列出已知的软件包的状态详细信息">列出已知的软件包的状态(详细信息)
</h5><ul>
<li>选项:<code>-s, --status [package-name...]</code><br>
该选项用于输出 <strong>dpkg 数据库中已知的</strong>软件包的状态(详细信息)。<br>
<strong>主要用于查询软件包的版本、依赖、配置状态等信息</strong>。<br>
可以提供一个模式用于查找特定的软件包,或者不给出模式,会列出所有已知的软件包。<br>
举例,如下:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ dpkg-query -s code
</span></span><span class="line"><span class="cl">Package: code
</span></span><span class="line"><span class="cl">Status: install ok installed
</span></span><span class="line"><span class="cl">Priority: optional
</span></span><span class="line"><span class="cl">Section: devel
</span></span><span class="line"><span class="cl">Installed-Size: <span class="m">446270</span>
</span></span><span class="line"><span class="cl">Maintainer: Microsoft Corporation &lt;vscode-linux@microsoft.com&gt;
</span></span><span class="line"><span class="cl">Architecture: amd64
</span></span><span class="line"><span class="cl">Version: 1.104.1-1758154125
</span></span><span class="line"><span class="cl">Replaces: visual-studio-code
</span></span><span class="line"><span class="cl">Provides: visual-studio-code
</span></span><span class="line"><span class="cl">Depends: ca-certificates, libasound2 <span class="o">(</span>&gt;<span class="o">=</span> 1.0.17<span class="o">)</span>, libatk-bridge2.0-0 <span class="o">(</span>&gt;<span class="o">=</span> 2.5.3<span class="o">)</span>, libatk1.0-0 <span class="o">(</span>&gt;<span class="o">=</span> 2.11.90<span class="o">)</span>, libatspi2.0-0 <span class="o">(</span>&gt;<span class="o">=</span> 2.9.90<span class="o">)</span>, libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.14<span class="o">)</span>, libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.16<span class="o">)</span>, libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.17<span class="o">)</span>, libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.2.5<span class="o">)</span>, libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.25<span class="o">)</span>, libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.28<span class="o">)</span>, libcairo2 <span class="o">(</span>&gt;<span class="o">=</span> 1.6.0<span class="o">)</span>, libcurl3-gnutls <span class="p">|</span> libcurl3-nss <span class="p">|</span> libcurl4 <span class="p">|</span> libcurl3, libdbus-1-3 <span class="o">(</span>&gt;<span class="o">=</span> 1.9.14<span class="o">)</span>, libexpat1 <span class="o">(</span>&gt;<span class="o">=</span> 2.1~beta3<span class="o">)</span>, libgbm1 <span class="o">(</span>&gt;<span class="o">=</span> 17.1.0~rc2<span class="o">)</span>, libglib2.0-0 <span class="o">(</span>&gt;<span class="o">=</span> 2.37.3<span class="o">)</span>, libgtk-3-0 <span class="o">(</span>&gt;<span class="o">=</span> 3.9.10<span class="o">)</span>, libgtk-3-0 <span class="o">(</span>&gt;<span class="o">=</span> 3.9.10<span class="o">)</span> <span class="p">|</span> libgtk-4-1, libnspr4 <span class="o">(</span>&gt;<span class="o">=</span> 2:4.9-2~<span class="o">)</span>, libnss3 <span class="o">(</span>&gt;<span class="o">=</span> 2:3.30<span class="o">)</span>, libnss3 <span class="o">(</span>&gt;<span class="o">=</span> 3.26<span class="o">)</span>, libpango-1.0-0 <span class="o">(</span>&gt;<span class="o">=</span> 1.14.0<span class="o">)</span>, libudev1 <span class="o">(</span>&gt;<span class="o">=</span> 183<span class="o">)</span>, libx11-6, libx11-6 <span class="o">(</span>&gt;<span class="o">=</span> 2:1.4.99.1<span class="o">)</span>, libxcb1 <span class="o">(</span>&gt;<span class="o">=</span> 1.9.2<span class="o">)</span>, libxcomposite1 <span class="o">(</span>&gt;<span class="o">=</span> 1:0.4.4-1<span class="o">)</span>, libxdamage1 <span class="o">(</span>&gt;<span class="o">=</span> 1:1.1<span class="o">)</span>, libxext6, libxfixes3, libxkbcommon0 <span class="o">(</span>&gt;<span class="o">=</span> 0.5.0<span class="o">)</span>, libxkbfile1 <span class="o">(</span>&gt;<span class="o">=</span> 1:1.1.0<span class="o">)</span>, libxrandr2, xdg-utils <span class="o">(</span>&gt;<span class="o">=</span> 1.0.2<span class="o">)</span>
</span></span><span class="line"><span class="cl">Recommends: libvulkan1
</span></span><span class="line"><span class="cl">Conflicts: visual-studio-code
</span></span><span class="line"><span class="cl">Description: Code editing. Redefined.
</span></span><span class="line"><span class="cl"> Visual Studio Code is a new choice of tool that combines the simplicity of
</span></span><span class="line"><span class="cl"> a code editor with what developers need <span class="k">for</span> the core edit-build-debug cycle.
</span></span><span class="line"><span class="cl"> See https://code.visualstudio.com/docs/setup/linux <span class="k">for</span> installation
</span></span><span class="line"><span class="cl"> instructions and FAQ.
</span></span><span class="line"><span class="cl">Homepage: https://code.visualstudio.com/
</span></span></code></pre></td></tr></table>
</div>
</div><h5 id="列出已知的软件包安装到系统上的文件">列出已知的软件包安装到系统上的文件
</h5><ul>
<li>选项:<code>-L, --listfiles package-name...</code><br>
该选项用于列出指定软件包安装到你系统上的文件。<br>
必须提供一个模式用于查找特定的软件包。<br>
举例,如下:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ dpkg-query -L code <span class="p">|</span> tail -5
</span></span><span class="line"><span class="cl">/usr/share/pixmaps
</span></span><span class="line"><span class="cl">/usr/share/pixmaps/vscode.png
</span></span><span class="line"><span class="cl">/usr/share/zsh
</span></span><span class="line"><span class="cl">/usr/share/zsh/vendor-completions
</span></span><span class="line"><span class="cl">/usr/share/zsh/vendor-completions/_code
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="查询文件归属">查询文件归属
</h4><ul>
<li>选项:<code>-S, --search filename-search-pattern...</code><br>
该选项用于查询系统中某个文件由哪个软件包提供。<br>
必须提供一个模式用于查找特定的软件包。<br>
举例,如下:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ dpkg-query -S /usr/share/appdata/code.appdata.xml
</span></span><span class="line"><span class="cl">code: /usr/share/appdata/code.appdata.xml
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="apt">apt
</h2><h3 id="工具介绍-3">工具介绍
</h3><p>apt 是 APT 软件包管理系统的前端。</p>
<p>APT 全称为 <em>Advanced Package Tool</em> ,是建立在 dpkg 之上的一套更高级的包管理系统。</p>
<p>apt 为 APT 软件包管理系统提供了一个高级的命令行接口。它旨在作为最终用户界面,并且默认启用一些更适合交互式使用的选项,与更专门的 APT 工具(如 apt-get 和 apt-cache )相比的话。可以理解为 apt 是 apt-get 和 apt-cache 的封装,它更现代,对用户更友好。</p>
<p>apt 基于 apt-get,而 apt-get 基于 dpkg ,因此 dpkg 和 apt 能识别彼此安装的 deb 软件包。</p>
<p><strong>与 dpkg 相比,apt 不假定用户已经将 .deb 软件包下载到本地或者能以 URL 的形式提供,其能够自动的从所用的<a class="link" href="#apt-%e4%bb%93%e5%ba%93" > Linux 发行版仓库</a>中下载并安装软件包。更重要的是其能够自动解析依赖关系,根据需求安装额外的库和软件包</strong>。</p>
<p>就像 dpkg 一样,apt 的大部分功能依赖其后端工具。观察 apt 的手册会发现其标明了它的功能来自于那个后端工具,如 <code>update (apt-get(8))</code>。详细的选项可以进一步阅读对应的手册来知晓功能,比如这里就应该阅读 <code>apt-get(8)</code> 手册。</p>
<p>可以参考<a class="link" href="#debian%e7%b3%bb%e7%bb%9f%e5%8c%85%e7%ae%a1%e7%90%86%e5%b7%a5%e5%85%b7%e6%80%9d%e7%bb%b4%e5%af%bc%e5%9b%be" >Debian系统包管理工具思维导图</a>理解各个工具之间的关系。</p>
<h3 id="apt-仓库">apt 仓库
</h3><p>apt 默认的软件存储库位置是在安装 Linux 发行版时设置的,仓库位置保存文件 <code>/etc/apt/sources.list</code> 中。<br>
举例,如下:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ cat /etc/apt/sources.list
</span></span><span class="line"><span class="cl">deb http://mirrors.aliyun.com/ubuntu/ noble main restricted universe multiverse
</span></span><span class="line"><span class="cl">deb-src http://mirrors.aliyun.com/ubuntu/ noble main restricted universe multiverse
</span></span><span class="line"><span class="cl">......
</span></span></code></pre></td></tr></table>
</div>
</div><p>在许多情况下,根本用不着添加/删除软件仓库,所以没必要该这个文件。但是,apt 只会从这些仓库拉取软件。此外,在搜索要安装或者更新的软件时,apt 也只检查这些仓库。如果你想为你的软件包管理系统加入一些额外的软件仓库,那就得修改文件了。</p>
<p>该文件中存在这如下结构或者说格式的文本:<br>
<code>deb(or deb-src) address distribution_name package_type_list</code></p>
<ul>
<li>deb 表明这是一个已编译程序的仓库源(即提供二进制包,用于下载 .deb 文件 )<br>
deb-src 表明这是一个源代码的仓库原(即提供源码包,用于下载 tarball、打包配置等文件 )</li>
<li>adress 是软件仓库的地址</li>
<li>distribution_name 是软件仓库的发行版的版本名称。<br>
比如上面的例子中为 noble,这并非表明当前用户使用的 Linux 发行版为 Ubuntu Noble Numbat (即 Ubuntu 24.04 LTS),只是说明这个 Linux 发行版正在使用 Ubuntu 24.04 LTS (Noble Numbat) 软件仓库。</li>
<li>package_type_list 表明仓库里有什么类型的软件包(可能并不止一个单词)。<br>
比如上面的例子中出现的 main restricted universe multiverse,还可能有 partner 等词。</li>
</ul>
<p>软件仓库网站或者各种软件包开发人员的网站上通常会提供上述格式的文本,你可以直接将这些文本复制/粘贴到 <code>sources.list</code> 文件中。这是添加仓库最安全的方式,最好不要仍由自己发挥,这一般会带来问题。</p>
<h3 id="主要功能-3">主要功能
</h3><h4 id="通过仓库获取最新的软件包信息">通过仓库获取最新的软件包信息
</h4><ul>
<li>操作:<code>update</code><br>
该选项用于从配置的所有软件源中获取最新的可用软件包信息,但不会安装或升级任何软件。<br>
其他命令基于此获取的软件包数据进行操作,例如执行软件包升级(upgrades)或搜索(search)并显示所有可供安装的软件包的详细信息。</li>
</ul>
<h4 id="列出所有可用的软件包">列出所有可用的软件包
</h4><ul>
<li>操作:<code>list</code><br>
用于显示仓库中所有可用的软件包,通过 <code>--installed</code> 选项可以只列出已经安装的软件包。<br>
举例,如下:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ apt list <span class="p">|</span> tail -3
</span></span><span class="line"><span class="cl">zziplib-bin/noble 0.13.72+dfsg.1-1.2build1 amd64
</span></span><span class="line"><span class="cl">zziplib-bin/noble 0.13.72+dfsg.1-1.2build1 i386
</span></span><span class="line"><span class="cl">zzuf/noble 0.15-2build3 amd64
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="搜索指定的软件包">搜索指定的软件包
</h4><ul>
<li>操作:<code>search</code><br>
用于从本地软件包信息缓存中搜索指定的软件包。默认会搜索名称或者描述中包含搜索关键字的软件包,可使用 <code>--names-only</code> 选项来指明只搜索名称。 <br>
举例,如下:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ apt search --names-only zsh
</span></span><span class="line"><span class="cl">zsh/noble,now 5.9-6ubuntu2 amd64 <span class="o">[</span>已安装<span class="o">]</span>
</span></span><span class="line"><span class="cl"> 具有很多特性的 Shell
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="查看指定软件包的信息">查看指定软件包的信息
</h4><ul>
<li>操作:<code>show</code><br>
用于本地软件包信息缓存搜索指定的软件包的信息,包括其依赖关系、安装和下载大小、软件包可用的源、软件包内容的描述等更多信息。<br>
能够显示软件包非常详细的元数据,是了解一个软件包的绝佳方式。<br>
举例,如下:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~$ apt show lsof
</span></span><span class="line"><span class="cl">Package: lsof
</span></span><span class="line"><span class="cl">Version: 4.95.0-1build3
</span></span><span class="line"><span class="cl">Priority: standard
</span></span><span class="line"><span class="cl">Section: utils
</span></span><span class="line"><span class="cl">Origin: Ubuntu
</span></span><span class="line"><span class="cl">Maintainer: Ubuntu Developers &lt;ubuntu-devel-discuss@lists.ubuntu.com&gt;
</span></span><span class="line"><span class="cl">Original-Maintainer: Andres Salomon &lt;dilinger@debian.org&gt;
</span></span><span class="line"><span class="cl">Bugs: https://bugs.launchpad.net/ubuntu/+filebug
</span></span><span class="line"><span class="cl">Installed-Size: <span class="m">486</span> kB
</span></span><span class="line"><span class="cl">Depends: libc6 <span class="o">(</span>&gt;<span class="o">=</span> 2.34<span class="o">)</span>, libselinux1 <span class="o">(</span>&gt;<span class="o">=</span> 3.1~<span class="o">)</span>, libtirpc3t64 <span class="o">(</span>&gt;<span class="o">=</span> 1.0.2<span class="o">)</span>
</span></span><span class="line"><span class="cl">Homepage: https://github.com/lsof-org/lsof
</span></span><span class="line"><span class="cl">Task: standard, ubuntu-wsl
</span></span><span class="line"><span class="cl">Download-Size: <span class="m">247</span> kB
</span></span><span class="line"><span class="cl">APT-Manual-Installed: no
</span></span><span class="line"><span class="cl">APT-Sources: http://mirrors.aliyun.com/ubuntu noble/main amd64 Packages
</span></span><span class="line"><span class="cl">Description: 列出打开文件的工具
</span></span><span class="line"><span class="cl"> Lsof 是一个 Unix 特有的诊断工具。它的名称代表 LiSt Open Files <span class="o">(</span>列出打
</span></span><span class="line"><span class="cl"> 开的文件<span class="o">)</span>,它也只做这个。它列出了所有被正在当前系统运行的进程打开的文 件的信息。
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="通过仓库或者本地安装软件包">通过仓库(或者本地)安装软件包
</h4><ul>
<li>操作:<code>install</code><br>
用于从仓库中安装指定的软件包,或者就像 dpkg 一样直接安装已下载到本地的 .deb 软件包(或以URL形式提供)。<br>
<strong>会自动读取安装的软件包的信息并处理依赖关系,有时会从仓库安装额外的包来满足依赖关系</strong>,这正是我们使用 apt 的一个重要的原因。<br>
<strong>提醒:使用前需要使用 <code>update</code> 操作获取最新的软件包信息,不然可能会导致无法知晓可用的软件包</strong>。<br>
举例,如下:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># 通过仓库下载并安装软件包</span>
</span></span><span class="line"><span class="cl">~$ sudo apt install git
</span></span><span class="line"><span class="cl">......
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 直接安装本地的软件包</span>
</span></span><span class="line"><span class="cl">~$ apt install ./code.deb
</span></span><span class="line"><span class="cl">......
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="通过仓库更新软件">通过仓库更新软件
</h4><ul>
<li>
<p>操作:<code>upgrade</code><br>
用于从通过 <code>sources.list</code> 配置的源中,安装当前系统上所有已安装软件包的可用升级。<br>
如果需要满足依赖关系,将安装新软件包,但永远不会删除现有软件包。<br>
如果某个软件包的升级需要移除一个已安装的软件包,则该软件包的升级将不会执行。<br>
<strong>提醒:使用前需要使用 <code>update</code> 操作获取最新的软件包信息,不然可能会导致无法知晓可用的升级</strong>。</p>
</li>
<li>
<p>操作:<code>full-upgrade</code><br>
执行与 <code>upgrade</code> 相同的功能,但如果需要升级整个系统,它将移除当前已安装的软件包。<br>
<code>full-upgrade</code> 在处理复杂的依赖关系时更彻底,但风险也更高,因为它可能会为了完成升级而删除一些软件包。在 Ubuntu 系统中,这个命令通常等同于 <code>dist-upgrade</code>。</p>
</li>
</ul>
<h4 id="卸载软件包-1">卸载软件包
</h4><ul>
<li>
<p>操作:<code>remove</code><br>
用于删除指定的软件包,但会保留对应的数据和配置文件。<br>
类似 <a class="link" href="#%e5%8d%b8%e8%bd%bd%e8%bd%af%e4%bb%b6%e5%8c%85" ><code>dpkg-deb -r</code></a>。<br>
<strong>如果软件包存在依赖,不会将依赖删除,请参考下面的 <code>automove</code></strong>。</p>
</li>
<li>
<p>操作:<code>purge</code><br>
用于删除指定的软件包,并且还会删除对应的数据和配置文件。<br>
类似 <a class="link" href="#%e5%8d%b8%e8%bd%bd%e8%bd%af%e4%bb%b6%e5%8c%85" ><code>dpkg-deb -P</code></a>。<br>
<strong>如果软件包存在依赖,不会将依赖删除,请参考下面的 <code>automove</code></strong>。</p>
</li>
<li>
<p>操作:<code>autoremove</code><br>
用于移除那些当初为了满足其他软件包的依赖关系而自动安装,但现在由于依赖关系变更或需要它们的软件包已被移除而不再需要的软件包。<br>
<strong>但是本人不建议你轻易使用,因为它的外号是依赖粉碎机,执行后可能会造成比较严重的后果</strong>。</p>
</li>
</ul>
<h3 id="彩蛋">彩蛋
</h3><p>apt 有一个著名的牛力彩蛋,具体如下:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18