mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-09-26 13:16:41 +08:00
431 lines
37 KiB
HTML
431 lines
37 KiB
HTML
<!DOCTYPE html>
|
||
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<head>
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
|
||
<link rel="icon" href="/static/favicon.png">
|
||
<title>10 软件的安装: 编译安装和包管理器安装有什么优势和劣势?.md.html</title>
|
||
<!-- Spectre.css framework -->
|
||
<link rel="stylesheet" href="/static/index.css">
|
||
<!-- theme css & js -->
|
||
<meta name="generator" content="Hexo 4.2.0">
|
||
</head>
|
||
<body>
|
||
<div class="book-container">
|
||
<div class="book-sidebar">
|
||
<div class="book-brand">
|
||
<a href="/">
|
||
<img src="/static/favicon.png">
|
||
<span>技术文章摘抄</span>
|
||
</a>
|
||
</div>
|
||
<div class="book-menu uncollapsible">
|
||
<ul class="uncollapsible">
|
||
<li><a href="/" class="current-tab">首页</a></li>
|
||
</ul>
|
||
<ul class="uncollapsible">
|
||
<li><a href="../">上一级</a></li>
|
||
</ul>
|
||
<ul class="uncollapsible">
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/00 开篇词 为什么大厂面试必考操作系统?.md.html">00 开篇词 为什么大厂面试必考操作系统?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/00 课前必读 构建知识体系,可以这样做!.md.html">00 课前必读 构建知识体系,可以这样做!</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/01 计算机是什么:“如何把程序写好”这个问题是可计算的吗?.md.html">01 计算机是什么:“如何把程序写好”这个问题是可计算的吗?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/02 程序的执行:相比 32 位,64 位的优势是什么?(上).md.html">02 程序的执行:相比 32 位,64 位的优势是什么?(上)</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/03 程序的执行:相比 32 位,64 位的优势是什么?(下).md.html">03 程序的执行:相比 32 位,64 位的优势是什么?(下)</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/04 构造复杂的程序:将一个递归函数转成非递归函数的通用方法.md.html">04 构造复杂的程序:将一个递归函数转成非递归函数的通用方法</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/05 存储器分级:L1 Cache 比内存和 SSD 快多少倍?.md.html">05 存储器分级:L1 Cache 比内存和 SSD 快多少倍?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/05 (1) 加餐 练习题详解(一).md.html">05 (1) 加餐 练习题详解(一)</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/06 目录结构和文件管理指令:rm -rf 指令的作用是?.md.html">06 目录结构和文件管理指令:rm -rf 指令的作用是?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/07 进程、重定向和管道指令:xargs 指令的作用是?.md.html">07 进程、重定向和管道指令:xargs 指令的作用是?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/08 用户和权限管理指令: 请简述 Linux 权限划分的原则?.md.html">08 用户和权限管理指令: 请简述 Linux 权限划分的原则?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/09 Linux 中的网络指令:如何查看一个域名有哪些 NS 记录?.md.html">09 Linux 中的网络指令:如何查看一个域名有哪些 NS 记录?</a>
|
||
</li>
|
||
<li>
|
||
<a class="current-tab" href="/专栏/重学操作系统-完/10 软件的安装: 编译安装和包管理器安装有什么优势和劣势?.md.html">10 软件的安装: 编译安装和包管理器安装有什么优势和劣势?</a>
|
||
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/11 高级技巧之日志分析:利用 Linux 指令分析 Web 日志.md.html">11 高级技巧之日志分析:利用 Linux 指令分析 Web 日志</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/12 高级技巧之集群部署:利用 Linux 指令同时在多台机器部署程序.md.html">12 高级技巧之集群部署:利用 Linux 指令同时在多台机器部署程序</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/12 (1)加餐 练习题详解(二).md.html">12 (1)加餐 练习题详解(二)</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/13 操作系统内核:Linux 内核和 Windows 内核有什么区别?.md.html">13 操作系统内核:Linux 内核和 Windows 内核有什么区别?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/14 用户态和内核态:用户态线程和内核态线程有什么区别?.md.html">14 用户态和内核态:用户态线程和内核态线程有什么区别?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/15 中断和中断向量:Javajs 等语言为什么可以捕获到键盘输入?.md.html">15 中断和中断向量:Javajs 等语言为什么可以捕获到键盘输入?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/16 WinMacUnixLinux 的区别和联系:为什么 Debian 漏洞排名第一还这么多人用?.md.html">16 WinMacUnixLinux 的区别和联系:为什么 Debian 漏洞排名第一还这么多人用?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/16 (1)加餐 练习题详解(三).md.html">16 (1)加餐 练习题详解(三)</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/17 进程和线程:进程的开销比线程大在了哪里?.md.html">17 进程和线程:进程的开销比线程大在了哪里?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/18 锁、信号量和分布式锁:如何控制同一时间只有 2 个线程运行?.md.html">18 锁、信号量和分布式锁:如何控制同一时间只有 2 个线程运行?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/19 乐观锁、区块链:除了上锁还有哪些并发控制方法?.md.html">19 乐观锁、区块链:除了上锁还有哪些并发控制方法?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/20 线程的调度:线程调度都有哪些方法?.md.html">20 线程的调度:线程调度都有哪些方法?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/21 哲学家就餐问题:什么情况下会触发饥饿和死锁?.md.html">21 哲学家就餐问题:什么情况下会触发饥饿和死锁?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/22 进程间通信: 进程间通信都有哪些方法?.md.html">22 进程间通信: 进程间通信都有哪些方法?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/23 分析服务的特性:我的服务应该开多少个进程、多少个线程?.md.html">23 分析服务的特性:我的服务应该开多少个进程、多少个线程?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/23 (1)加餐 练习题详解(四).md.html">23 (1)加餐 练习题详解(四)</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/24 虚拟内存 :一个程序最多能使用多少内存?.md.html">24 虚拟内存 :一个程序最多能使用多少内存?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/25 内存管理单元: 什么情况下使用大内存分页?.md.html">25 内存管理单元: 什么情况下使用大内存分页?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/26 缓存置换算法: LRU 用什么数据结构实现更合理?.md.html">26 缓存置换算法: LRU 用什么数据结构实现更合理?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/27 内存回收上篇:如何解决内存的循环引用问题?.md.html">27 内存回收上篇:如何解决内存的循环引用问题?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/28 内存回收下篇:三色标记-清除算法是怎么回事?.md.html">28 内存回收下篇:三色标记-清除算法是怎么回事?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/28 (1)加餐 练习题详解(五).md.html">28 (1)加餐 练习题详解(五)</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/29 Linux 下的各个目录有什么作用?.md.html">29 Linux 下的各个目录有什么作用?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/30 文件系统的底层实现:FAT、NTFS 和 Ext3 有什么区别?.md.html">30 文件系统的底层实现:FAT、NTFS 和 Ext3 有什么区别?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/31 数据库文件系统实例:MySQL 中 B 树和 B+ 树有什么区别?.md.html">31 数据库文件系统实例:MySQL 中 B 树和 B+ 树有什么区别?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/32 HDFS 介绍:分布式文件系统是怎么回事?.md.html">32 HDFS 介绍:分布式文件系统是怎么回事?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/32 (1)加餐 练习题详解(六).md.html">32 (1)加餐 练习题详解(六)</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/33 互联网协议群(TCPIP):多路复用是怎么回事?.md.html">33 互联网协议群(TCPIP):多路复用是怎么回事?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/34 UDP 协议:UDP 和 TCP 相比快在哪里?.md.html">34 UDP 协议:UDP 和 TCP 相比快在哪里?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/35 Linux 的 IO 模式:selectpollepoll 有什么区别?.md.html">35 Linux 的 IO 模式:selectpollepoll 有什么区别?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/36 公私钥体系和网络安全:什么是中间人攻击?.md.html">36 公私钥体系和网络安全:什么是中间人攻击?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/36 (1)加餐 练习题详解(七).md.html">36 (1)加餐 练习题详解(七)</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/37 虚拟化技术介绍:VMware 和 Docker 的区别?.md.html">37 虚拟化技术介绍:VMware 和 Docker 的区别?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/38 容器编排技术:如何利用 K8s 和 Docker Swarm 管理微服务?.md.html">38 容器编排技术:如何利用 K8s 和 Docker Swarm 管理微服务?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/39 Linux 架构优秀在哪里.md.html">39 Linux 架构优秀在哪里</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/40 商业操作系统:电商操作系统是不是一个噱头?.md.html">40 商业操作系统:电商操作系统是不是一个噱头?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/40 (1)加餐 练习题详解(八).md.html">40 (1)加餐 练习题详解(八)</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/重学操作系统-完/41 结束语 论程序员的发展——信仰、选择和博弈.md.html">41 结束语 论程序员的发展——信仰、选择和博弈</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
|
||
<div class="sidebar-toggle-inner"></div>
|
||
</div>
|
||
<script>
|
||
function add_inner() {
|
||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||
inner.classList.add('show')
|
||
}
|
||
function remove_inner() {
|
||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||
inner.classList.remove('show')
|
||
}
|
||
function sidebar_toggle() {
|
||
let sidebar_toggle = document.querySelector('.sidebar-toggle')
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
let content = document.querySelector('.off-canvas-content')
|
||
if (sidebar_toggle.classList.contains('extend')) { // show
|
||
sidebar_toggle.classList.remove('extend')
|
||
sidebar.classList.remove('hide')
|
||
content.classList.remove('extend')
|
||
} else { // hide
|
||
sidebar_toggle.classList.add('extend')
|
||
sidebar.classList.add('hide')
|
||
content.classList.add('extend')
|
||
}
|
||
}
|
||
function open_sidebar() {
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
let overlay = document.querySelector('.off-canvas-overlay')
|
||
sidebar.classList.add('show')
|
||
overlay.classList.add('show')
|
||
}
|
||
function hide_canvas() {
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
let overlay = document.querySelector('.off-canvas-overlay')
|
||
sidebar.classList.remove('show')
|
||
overlay.classList.remove('show')
|
||
}
|
||
</script>
|
||
<div class="off-canvas-content">
|
||
<div class="columns">
|
||
<div class="column col-12 col-lg-12">
|
||
<div class="book-navbar">
|
||
<!-- For Responsive Layout -->
|
||
<header class="navbar">
|
||
<section class="navbar-section">
|
||
<a onclick="open_sidebar()">
|
||
<i class="icon icon-menu"></i>
|
||
</a>
|
||
</section>
|
||
</header>
|
||
</div>
|
||
<div class="book-content" style="max-width: 960px; margin: 0 auto;
|
||
overflow-x: auto;
|
||
overflow-y: hidden;">
|
||
<div class="book-post">
|
||
<p id="tip" align="center"></p>
|
||
<div><h1>10 软件的安装: 编译安装和包管理器安装有什么优势和劣势?</h1>
|
||
<p><strong>今天给你带来的面试题是:编译安装和包管理器安装有什么优势和劣势</strong>?为了搞清楚这个问题,就引出了今天的话题,在 Linux 上如何安装程序。</p>
|
||
<p>在 Linux 上安装程序大概有 2 种思路:</p>
|
||
<ol>
|
||
<li>直接编译源代码;</li>
|
||
<li>使用包管理器。</li>
|
||
</ol>
|
||
<p>受开源运动影响,Linux 上很多软件都可以拿到源代码,这也是 Linux 能取得成功的一个重要原因。接下来我们先尝试用包管理器安装应用,然后再用一个实战的例子,教你如何编译安装<code>nginx</code>。</p>
|
||
<h3>包管理器使用</h3>
|
||
<p>Linux 下的应用程序多数以软件包的形式发布,用户拿到对应的包之后,使用包管理器进行安装。说到包管理器,就要提到<code>dpkg</code>和<code>rpm</code>。</p>
|
||
<p>我们先说说包。 Linux 下两大主流的包就是<code>rpm</code>和<code>dpkg</code>。</p>
|
||
<p><code>dpkg</code>(debian package),是<code>linux</code>一个主流的社区分支开发出来的。社区就是开源社区,有很多世界顶级的程序员会在社区贡献代码,比如 github。一般衍生于<code>debian</code>的 Linux 版本都支持<code>dpkg</code>,比如<code>ubuntu</code>。</p>
|
||
<p><code>rpm</code>(redhatpackage manager)。在正式讲解之前,我们先来聊聊 RedHat 这家公司。</p>
|
||
<p>RedHat 是一个做 Linux 的公司,你可以把它理解成一家“保险公司”。 很多公司购买红帽的服务,是为了给自己的业务上一个保险。以防万一哪天公司内部搞不定 Linux 底层,或者底层有 Bug,再或者底层不适合当下的业务发展,需要修改等问题,红帽的工程师都可以帮企业解决。</p>
|
||
<p>再比如,RedHat 收购了JBoss,把 JBoss 改名为 WildFly。 像 WildFly 这种工具更多是面向企业级,比如没有大量研发团队的企业会更倾向使用成熟的技术。RedHat 公司也有自己的 Linux,就叫作 RedHat。RedHat 系比较重要的 Linux 有 RedHat/Fedora 等。</p>
|
||
<p>无论是<code>dpkg</code>还是<code>rpm</code>都抽象了自己的包格式,就是以<code>.dpkg</code>或者<code>.rpm</code>结尾的文件。</p>
|
||
<p><code>dpkg</code>和<code>rpm</code>也都提供了类似的能力:</p>
|
||
<ul>
|
||
<li>查询是否已经安装了某个软件包;</li>
|
||
<li>查询目前安装了什么软件包;</li>
|
||
<li>给定一个软件包,进行安装;</li>
|
||
<li>删除一个安装好的软件包。</li>
|
||
</ul>
|
||
<p>关于<code>dpkg</code>和<code>rpm</code>的具体用法,你可以用<code>man</code>进行学习。接下来我们聊聊<code>yum</code>和<code>apt</code>。</p>
|
||
<h4>自动依赖管理</h4>
|
||
<p>Linux 是一个开源生态,因此工具非常多。工具在给用户使用之前,需要先打成<code>dpkg</code>或者<code>rpm</code>包。 有的时候一个包会依赖很多其他的包,而<code>dpkg</code>和<code>rpm</code>不会对这种情况进行管理,有时候为了装一个包需要先装十几个依赖的包,过程非常艰辛!因此现在多数情况都在用<code>yum</code>和<code>apt</code>。</p>
|
||
<p><strong>yum</strong></p>
|
||
<p>你可能会说,我不用<code>yum</code>也不用<code>apt</code>,我只用<code>docker</code>。首先给你一个连击 666,然后我还是要告诉你,如果你做<code>docker</code>镜像,那么还是要用到<code>yum</code>和<code>apt</code>,因此还是有必要学一下。</p>
|
||
<p><code>yum</code>的全名是 Yellodog Updator,Modified。 看名字就知道它是基于<code>Yellodog Updator</code>这款软件修改而来的一个工具。<code>yum</code>是 Python 开发的,提供的是<code>rpm</code>包,因此只有<code>redhat</code>系的 Linux,比如 Fedora,Centos 支持<code>yum</code>。<code>yum</code>的主要能力就是帮你解决下载和依赖两个问题。</p>
|
||
<p>下载之所以是问题,是因为 Linux 生态非常庞大,有时候用户不知道该去哪里下载一款工具。比如用户想安装<code>vim</code>,只需要输入<code>sudo yum install vim</code>就可以安装了。<code>yum</code>的服务器收集了很多<code>linux</code>软件,因此<code>yum</code>会帮助用户找到<code>vim</code>的包。</p>
|
||
<p>另一方面,<code>yum</code>帮助用户解决了很多依赖,比如用户安装一个软件依赖了 10 个其他的软件,<code>yum</code>会把这 11 个软件一次性的装好。</p>
|
||
<p>关于<code>yum</code>的具体用法,你可以使用man工具进行学习。</p>
|
||
<p><strong>apt</strong></p>
|
||
<p>接下来我们来重点说说<code>apt</code>,然后再一起尝试使用。因为我这次是用<code>ubuntu</code>Linux 给你教学,所以我以 apt 为例子,yum 的用法是差不多的,你可以自己 man 一下。</p>
|
||
<p><code>apt</code>全名是 Advanced Packaging Tools,是一个<code>debian</code>及其衍生 Linux 系统下的包管理器。由于<code>advanced</code>(先进)是相对于<code>dpkg</code>而言的,因此它也能够提供和<code>yum</code>类似的下载和依赖管理能力。比如在没有<code>vim</code>的机器上,我们可以用下面的指令安装<code>vim</code>。如下图所示:</p>
|
||
<p><img src="assets/CgqCHl99kUCAc2xOAAHulKDtr4U742.png" alt="png" /></p>
|
||
<p>然后用<code>dpkg</code>指令查看 vim 的状态是<code>ii</code>。第一个<code>i</code>代表期望状态是已安装,第二个<code>i</code>代表实际状态是已安装。</p>
|
||
<p>下面我们卸载<code>vim</code>,再通过<code>dpkg</code>查看,如下图所示:</p>
|
||
<p><img src="assets/CgqCHl99kUuAJZSuAAW-FE-CgIY627.png" alt="png" /></p>
|
||
<p><img src="assets/CgqCHl99kVCAT9-sAAJPZUhXt9k401.png" alt="png" /></p>
|
||
<p>我们看到 vim 的状态从<code>ii</code>变成了<code>rc</code>,<code>r</code>是期望删除,<code>c</code>是实际上还有配置文件遗留。 如果我们想彻底删除配置文件,可以使用<code>apt purge</code>,就是彻底清除的意思,如下图所示:</p>
|
||
<p><img src="assets/Ciqc1F99kViANbVLAAPQJy3qAX8926.png" alt="png" /></p>
|
||
<p>再使用<code>dpkg -l</code>时,<code>vim</code>已经清除了。</p>
|
||
<p><img src="assets/Ciqc1F99kV-ACJvxAAIopnvusfs472.png" alt="png" /></p>
|
||
<p>期待结果是<code>u</code>就是 unkonw(未知)说明已经没有了。实际结果是<code>n</code>,就是 not-installed(未安装)。</p>
|
||
<p>如果想查询<code>mysql</code>相关的包,可以使用<code>apt serach mysql</code>,这样会看到很多和<code>mysql</code>相关的包,如下图所示:</p>
|
||
<p><img src="assets/CgqCHl99kWeANmD6AAUugWzWDUE531.png" alt="png" /></p>
|
||
<p>如果我们想精确查找一个叫作<code>mysql-server</code>的包,可以用<code>apt list</code>。</p>
|
||
<p><img src="assets/Ciqc1F99kWyAf1pzAAFI7ot6YSY175.png" alt="png" /></p>
|
||
<p>这里我们找到了<code>mysql-server</code>包。</p>
|
||
<p>另外有时候国内的<code>apt</code>服务器速度比较慢,你可以尝试使用阿里云的镜像服务器。具体可参考我下面的操作:</p>
|
||
<pre><code>cat /etc/apt/sources.list
|
||
--以下是文件内容--
|
||
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
|
||
deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
|
||
deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
|
||
deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
|
||
deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
|
||
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
|
||
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
|
||
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
|
||
deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
|
||
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
|
||
</code></pre>
|
||
<p>镜像地址可以通过<code>/etc/apt/sources.list</code>配置,注意<code>focal</code>是我用的<code>ubuntu</code>版本,你可以使用<code>sudo lsb_release</code>查看自己的 Ubuntu 版本。如果你想用我上面给出的内容覆盖你的<code>sources.list</code>,只需把版本号改成你自己的。注意,每个<code>ubuntu</code>版本都有自己的代号。</p>
|
||
<p><img src="assets/CgqCHl99kYCARaKvAAGzk1pe8DY132.png" alt="png" /></p>
|
||
<p>通过上面的学习,相信你已经逐渐了解了包管理器的基本概念和使用。如果你是<code>centos</code>或者<code>fedora</code>,需要自己<code>man</code>一下<code>yum</code>。</p>
|
||
<h3>编译安装 Nginx</h3>
|
||
<p>接下来我们说说编译安装 Nginx(发音是 engine X),是一个家喻户晓的 Web 服务器。 它的发明者是俄国的伊戈尔·赛索耶夫。赛索耶夫 2002 年开始写 Nginx,主要目的是解决同一个互联网节点同时进入大量并发请求的问题。注意,大量并发请求不是大量 QPS 的意思,QPS 是吞吐量大,需要快速响应,而高并发时则需要合理安排任务调度。</p>
|
||
<p>后来塞索耶夫成立了 Nginx 公司, 2018 年估值到达到 4.3 亿美金。现在基本上国内大厂的 Web 服务器都是基于 Nginx,只不过进行了特殊的修改,比如淘宝用 Tengine。</p>
|
||
<p>下面我们再来看看源码安装,在 Linux 上获取<code>nginx</code>源码,可以去搜索 <a href="https://nginx.org/en/docs/">Nginx 官方网站</a>,一般都会提供源码包。</p>
|
||
<p><img src="assets/CgqCHl99kYmAXQUyAADGX8gwStA669.png" alt="png" /></p>
|
||
<p>如上图所示,可以看到 nginx-1.18.0 的网址是:<a href="https://nginx.org/download/nginx-1.19.2.tar.gz">http://nginx.org/download/nginx-1.19.2.tar.gz</a>。然后我们用 wget 去下载这个包。 wget 是 GNU 项目下的下载工具,GNU 是早期<code>unix</code>项目的一个变种。<code>linux</code>下很多工具都是从<code>unix</code>继承来的,这就是开源的好处,很多工具不用再次开发了。你可能很难想象<code>windows</code>下的命令工具可以在<code>linux</code>下用,但是<code>linux</code>下的工具却可以在任何系统中用。 因此,<code>linux</code>下面的工具发展速度很快,如今已成为最受欢迎的服务器操作系统。</p>
|
||
<p>当然也有同学的机器上没有<code>wget</code>,那么你可以用<code>apt</code>安装一下。</p>
|
||
<ul>
|
||
<li>第一步:下载源码。我们使用<code>wget</code>下载<code>nginx</code>源码包:</li>
|
||
</ul>
|
||
<p><img src="assets/Ciqc1F99kZWABdtDAAPejhy3vW4914.png" alt="png" /></p>
|
||
<p>可以像我这样使用<code>cd</code>先切换到家目录。</p>
|
||
<ul>
|
||
<li>第二步:解压。我们解压下载好的<code>nginx</code>源码包。</li>
|
||
</ul>
|
||
<p><img src="assets/CgqCHl99kZ2AaXuiAAH8DdruTtI020.png" alt="png" /></p>
|
||
<p>用<code>ls</code>发现包已经存在了,然后使用<code>tar</code>命令解压。</p>
|
||
<p><code>tar</code>是用来打包和解压用的。之所以叫作<code>tar</code>是有一些历史原因:<code>t</code>代表<code>tape</code>(磁带);<code>ar</code>是 archive(档案)。因为早期的存储介质很小,人们习惯把文件打包然后存储到磁带上,那时候<code>unix</code>用的命令就是<code>tar</code>。因为<code>linux</code>是个开源生态,所以就沿袭下来继续使用<code>tar</code>。</p>
|
||
<p><code>-x</code>代表 extract(提取)。-z代表<code>gzip</code>,也就是解压<code>gz</code>类型的文件。<code>-v</code>代表 verbose(显示细节),如果你不输入<code>-v</code>,就不会打印解压过程了。<code>-f</code>代表 file,这里指的是要操作文件,而不是磁带。 所以<code>tar</code>解压通常带有<code>x</code>和<code>f</code>,打包通常是<code>c</code>就是 create 的意思。</p>
|
||
<ul>
|
||
<li>第三步:配置和解决依赖。解压完,我们进入<code>nginx</code>的目录看一看。 如下图所示:</li>
|
||
</ul>
|
||
<p><img src="assets/CgqCHl99kaWALMdgAAD3nrZGCkk000.png" alt="png" /></p>
|
||
<p>可以看到一个叫作<code>configure</code>的文件是绿色的,也就是可执行文件。然后我们执行 configure 文件进行配置,这个配置文件来自一款叫作<code>autoconf</code>的工具,也是 GNU 项目下的,说白了就是<code>bash</code>(Bourne Shell)下的安装打包工具(就是个安装程序)。这个安装程序支持很多配置,你可以用<code>./configure --help</code>看到所有的配置项,如下图所示:</p>
|
||
<p><img src="assets/Ciqc1F99kayAZu1TAAJeaol9wiw800.png" alt="png" /></p>
|
||
<p>这里有几个非常重要的配置项,叫作<code>prefix</code>。<code>prefix</code>配置项决定了软件的安装目录。如果不配置这个配置项,就会使用默认的安装目录。<code>sbin-path</code>决定了<code>nginx</code>的可执行文件的位置。<code>conf-path</code>决定了<code>nginx</code>配置文件的位置。我们都使用默认,然后执行<code>./configure</code>,如下图所示:</p>
|
||
<p><img src="assets/Ciqc1F99kbKAYqiXAAEc3ZFDVtE635.png" alt="png" /></p>
|
||
<p><code>autoconf</code>进行依赖检查的时候,报了一个错误,cc 没有找到。这是因为机器上没有安装<code>gcc</code>工具,gcc 是家喻户晓的工具套件,全名是 GNU Compiler Collection——里面涵盖了包括 c/c++ 在内的多门语言的编译器。</p>
|
||
<p>我们用包管理器,安装<code>gcc</code>,如下图所示。安装<code>gcc</code>通常是安装<code>build-essential</code>这个包。</p>
|
||
<p><img src="assets/CgqCHl99kbqAG6m9AARoq2Xsv_8899.png" alt="png" /></p>
|
||
<p>安装完成之后,再执行<code>./configure</code>,如下图所示:</p>
|
||
<p><img src="assets/CgqCHl99kcOAAUTtAAS2nlzDoGk494.png" alt="png" /></p>
|
||
<p>我们看到配置程序开始执行。但是最终报了一个错误,如下图所示:</p>
|
||
<p><img src="assets/CgqCHl99kcqAGqIuAAHKhlCMtYs244.png" alt="png" /></p>
|
||
<p>报错的内容是,<code>nginx</code>的<code>HTTP rewrite</code>模块,需要<code>PCRE</code>库。 PCRE 是<code>perl</code>语言的兼容正则表达式库。<code>perl</code>语言一直以支持原生正则表达式,而受到广大编程爱好者的喜爱。我曾经看到过一个 IBM 的朋友用<code>perl</code>加上<code>wget</code>就实现了一个简单的爬虫。接下来,我们开始安装<code>PCRE</code>。</p>
|
||
<p>一般这种依赖库,会叫<code>pcre-dev</code>或者<code>libpcre</code>。用<code>apt</code>查询了一下,然后<code>grep</code>。</p>
|
||
<p><img src="assets/CgqCHl99kdKATX0xAAgMkowaX1E974.png" alt="png" /></p>
|
||
<p>我们看到有<code>pcre2</code>也有<code>pcre3</code>。这个时候可以考虑试试<code>pcre3</code>。</p>
|
||
<p><img src="assets/CgqCHl99kdqACqo1AAfnaBqjC1Y752.png" alt="png" /></p>
|
||
<p>安装完成之后再试试<code>./configure</code>,提示还需要<code>zlib</code>。然后我们用类似的方法解决<code>zlib</code>依赖。</p>
|
||
<p><img src="assets/CgqCHl99keKACHklAAVMkWAY8Es203.png" alt="png" /></p>
|
||
<p><code>zlib</code>包的名字叫<code>zlib1g</code>不太好找,需要查资料才能确定是这个名字。</p>
|
||
<p>我们再尝试配置,终于配置成功了。</p>
|
||
<p><img src="assets/Ciqc1F99ke2AFl_pAAcxoAUgdw0867.png" alt="png" /></p>
|
||
<ul>
|
||
<li>第四步:编译和安装。</li>
|
||
</ul>
|
||
<p>通常配置完之后,我们输入<code>make && sudo make install</code>进行编译和安装。<code>make</code>是<code>linux</code>下面一个强大的构建工具。<code>autoconf</code>也就是<code>./configure</code>会在当前目录下生成一个 MakeFile 文件。<code>make</code>会根据<code>MakeFile</code>文件编译整个项目。编译完成后,能够形成和当前操作系统以及 CPU 指令集兼容的二进制可执行文件。然后再用<code>make install</code>安装。<code>&&</code>符号代表执行完<code>make</code>再去执行<code>make installl</code>。</p>
|
||
<p><img src="assets/Ciqc1F99kfaAFXguAAr_SGo4e8E213.png" alt="png" /></p>
|
||
<p>你可以看到编译是个非常慢的活。等待了差不多 1 分钟,终于结束了。<code>nginx</code>被安装到了<code>/usr/local/nginx</code>中,如果需要让<code>nginx</code>全局执行,可以设置一个软连接到<code>/usr/local/bin</code>,具体如下:</p>
|
||
<pre><code>ln -sf /usr/local/nginx/sbin/nginx /usr/local/sbin/nginx
|
||
</code></pre>
|
||
<h4>为什么会有编译安装?</h4>
|
||
<p>学完整个编译安装 Ngnix 过程后,你可能会问,为什么会有编译安装这么复杂的事情。</p>
|
||
<p>原来使用 C/C++ 写的程序存在一个交叉编译的问题。就是写一次程序,在很多个平台执行。而不同指令集的 CPU 指令,还有操作系统的可执行文件格式是不同的。因此,这里有非常多的现实问题需要解决。一般是由操作系统的提供方,比如 RedHat 来牵头解决这些问题。你可以用<code>apt</code>等工具提供给用户已经编译好的包。<code>apt</code>会自动根据用户的平台类型选择不同的包。</p>
|
||
<p>但如果某个包没有在平台侧注册,也没有提供某个 Linux 平台的软件包,我们就需要回退到编译安装,通过源代码直接在某个平台安装。</p>
|
||
<h3>总结</h3>
|
||
<p>这节课我们学习了在 Linux 上安装软件,简要介绍了<code>dpkg</code>和<code>rpm</code>,然后介绍了能够解决依赖和帮助用户下载的<code>yum</code>和<code>apt</code>。重点带你使用了<code>apt</code>,在这个过程中看到了强大的包管理机制,今天的<code>maven</code>、<code>npm</code>、<code>pip</code>都继承了这样一个特性。最后我们还尝试了一件高难度的事情,就是编译安装<code>nginx</code>。</p>
|
||
<p><strong>那么通过这节课的学习,你现在可以来回答本节关联的面试题目:编译安装和包管理安装有什么优势和劣势了吗?</strong></p>
|
||
<p>老规矩,请你先在脑海里构思下给面试官的表述,并把你的思考写在留言区,然后再来看我接下来的分析。</p>
|
||
<p><strong>【解析】</strong> 包管理安装很方便,但是有两点劣势。</p>
|
||
<p>第一点是需要提前将包编译好,因此有一个发布的过程,如果某个包没有发布版本,或者在某个平台上找不到对应的发布版本,就需要编译安装。</p>
|
||
<p>第二点就是如果一个软件的定制程度很高,可能会在编译阶段传入参数,比如利用<code>configure</code>传入配置参数,这种时候就需要编译安装。</p>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<div style="float: left">
|
||
<a href="/专栏/重学操作系统-完/09 Linux 中的网络指令:如何查看一个域名有哪些 NS 记录?.md.html">上一页</a>
|
||
</div>
|
||
<div style="float: right">
|
||
<a href="/专栏/重学操作系统-完/11 高级技巧之日志分析:利用 Linux 指令分析 Web 日志.md.html">下一页</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
|
||
</div>
|
||
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"70997d5d8fba3cfa","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
|
||
</body>
|
||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
|
||
<script>
|
||
window.dataLayer = window.dataLayer || [];
|
||
function gtag() {
|
||
dataLayer.push(arguments);
|
||
}
|
||
gtag('js', new Date());
|
||
gtag('config', 'G-NPSEEVD756');
|
||
var path = window.location.pathname
|
||
var cookie = getCookie("lastPath");
|
||
console.log(path)
|
||
if (path.replace("/", "") === "") {
|
||
if (cookie.replace("/", "") !== "") {
|
||
console.log(cookie)
|
||
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
|
||
}
|
||
} else {
|
||
setCookie("lastPath", path)
|
||
}
|
||
function setCookie(cname, cvalue) {
|
||
var d = new Date();
|
||
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
|
||
var expires = "expires=" + d.toGMTString();
|
||
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
|
||
}
|
||
function getCookie(cname) {
|
||
var name = cname + "=";
|
||
var ca = document.cookie.split(';');
|
||
for (var i = 0; i < ca.length; i++) {
|
||
var c = ca[i].trim();
|
||
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
|
||
}
|
||
return "";
|
||
}
|
||
</script>
|
||
</html>
|