序言
你将学到什么
本书是为计算机相关专业的Linux基础课程编写,也适合初学Linux的读者。如果你有些基础,本书也能查漏补缺。不要一次性看完本书,需要什么看什么,才是正确方法。
本书降低了Linux学习门槛,让读者有选择的在十分钟甚至一分钟内解决问题,快速、简单、连续、基础是本书的基本原则。本书还介绍了很多重要的Linux使用技巧,也提供了有关远程主机连接设置、文件检索、文档查询等内容。
应当具备的基础知识
本书假设读者已经掌握基本的计算机知识:
-
了解鼠标、键盘、屏幕、硬盘(分区)、WIFI、网线等常用电脑软硬件;
-
了解Windows控制面板,了解如何在Windows上安装软件;
-
有简单的网络知识,比如IP地址;
-
对Linux有简单的认识,知道或听说过Linux发行版名称。
本书假设读者没有Linux基础,内容安排是从零开始的。因此,对于那些不是计算机相关专业的读者来说,本书也是适用的。 需要指出的是,根据读者不同的知识背景,本书有多种不同的学习方案。对于那些有较强计算机基础的读者来说,可以有选择地学习。
关于Linux
通过本入门指南学习Linux基础,你将借助Linux强大的魔力、经验和技巧让生活更轻松,效果立竿见影。本书内容教你如何使用终端学习Linux,旨在为你打下坚实的基础,让Linux为你服务。最终,你不会成为Linux专家。如果这是你想要的(你应该这样做,这会让你变得更好),你会在路上一帆风顺,拥有正确的知识和技能来帮助你达到目标。
你将按照我准备的十章入门指南学习Linux。这里有直白的文字、命令说明、例子、捷径和最佳实践。
首先,Linux看起来令人生畏、复杂和害怕。实际上,Linux非常简单直接(学过的人都这么说),一旦你完成了下面的部分,你就会明白发生了什么。
Linux的哲学:每个程序只做一件事。 Linux提供一堆砖块,你用砖块组合创造出特定的工具(集),用来解决某件事情。只要有一点创造力和逻辑思维,加上对程序模块工作方式的理解,你就可以组装出几乎能做任何事的工具(集)。我喜欢 "偷懒"
才用Linux。
可能有个问题在你脑子闪过,
"为什么我要麻烦学习Linux?图形界面更好用,也能很好的完成我所想的。"
某种程度上你是对的,我绝对不建议你抛弃图形界面。有些任务适合图形界面,文字处理、视频编辑是最好的例子。同时,有些任务更适合Linux,比如数据处理(报告)、文件管理。在这两种环境中,有些任务处理起来又没什么不同。将Linux加入你的武器库,才能如虎添翼。像往常一样,挑选合适的工具做事。
本书的组织
本书分为十三个章节。通常,我推荐你按顺序学习。假如你阅读本书是为了特定的需求,请忽略我的建议。你现在可以开始学习,或者阅读下面的内容,进一步了解本书。
-
安装虚拟机 - 熟悉虚拟机软件基本使用,并安装CentOS7;
-
客户端工具 - 介绍客户端工具,怎样使用工具连接远程主机;
-
传输文件 - 学习怎样用MobaXterm或
scp
命令上传下载文件或目录; -
文件、目录与路径 - 了解什么是文件,什么是目录,认识相对路径和绝对路径;
-
文件和目录管理 - 练习文件和目录的创建、查看、编辑、压缩和解压等基础操作;
-
文件属性 - 了解用户、组和文件权限,熟悉基本操作;
-
输入输出重定向 - 了解标准输入、标准输出、标准错误;
-
管道 - 了解命令管道的组合应用;
-
常用命令 - 认识高频使用的Linux命令,练习基本使用;
-
内容搜索 - 练习搜索文件内容;
-
文件定位 - 增强文件检索能力;
-
软件包管理 - 练习安装卸载软件包,查看软件包信息等;
-
服务管理 - 关于服务管理的最佳实践。
1. 安装虚拟机
为方便练习,推荐使用虚拟机安装Linux。学会用最关键,以后再考虑在笔记本、PC或服务器等真机上安装Linux。
提到虚拟机软件,你可能听说过 VMware Workstation
(下称 VM
)。VM
功能丰富又强大,自然价格不便宜。
我不推荐使用 VM
的破解版,可能出现各种莫名问题,不稳定,捆绑软件甚至病毒。同时,作为IT行业的(可能)从业者,希望你一样尊重作者的版权。
VirtualBox
(下称 VBOX
)是一款免费、简单好用、稳定的虚拟机软件,用过的人都说好。
关于Linux发行版,我们选择红帽系、免费、稳定好用的CentOS。为什么不选择Ubuntu?因为,多数企业选择红帽或CentOS。
本教程将使用VBOX和CentOS,让你快速学会Linux基本使用。
VBOX依赖CPU的虚拟化支持,否则会提示“虚拟化未开启”之类的错误。 笔记本或台式机通常默认开启了CPU虚拟化支持。
|
1.1. 下载软件
请选择速度快的下载地址 |
1.1.1. 虚拟机软件
- VBOX安装包
- VBOX扩展包
1.1.2. CentOS7镜像文件
访问下载服务器地址,找到安装光盘的ISO文件,下载之。
建议下载迷你版安装光盘,文件名带 Minimal
字样。
如,"CentOS-7-x86_64-Minimal-2009.iso"
。
1.2. VirtualBox介绍
VirtualBox官网 |
VirtualBox是一款强大的x86和AMD64/Intel64虚拟化产品,适用于企业和个人。作为通用的x86硬件全虚拟化器,志在服务器、桌面和嵌入式领域。
VirtualBox有极其丰富的功能和高性能以满足企业客户,同时也是唯一一款使用GPL协议开源的虚拟机软件,无需购买即可使用所有(高级)功能。
当前,VM可以运行在以下系统上:
- Windows hosts (64-bit)
-
-
Windows 8.1
-
Windows 10 RTM (1507 / 2015 LTSB) build 10240
-
Windows 10 Anniversary Update (1607 / 2016 LTSB) build 14393
-
Windows 10 Fall Creators Update (1709) build 16299
-
Windows 10 April 2018 Update (1803) build 17134
-
Windows 10 October 2018 Update (1809 / 2019 LTSC) build 17763
-
Windows 10 May 2019 Update (19H1 / 1903) build 18362
-
Windows 10 November 2019 Update (19H2 / 1909) build 18363
-
Windows Server 2012
-
Windows Server 2012 R2
-
Windows Server 2016
-
Windows Server 2019
-
- Mac OS X hosts (64-bit)
-
-
10.13 (High Sierra)
-
10.14 (Mojave)
-
10.15 (Catalina)
-
- Linux hosts (64-bit). Includes the following
-
-
Ubuntu 18.04 LTS, 19.03 and 19.10
-
Debian GNU/Linux 9 ("Stretch") and 10 ("Buster")
-
Oracle Linux 6, 7 and 8
-
Red Hat Enterprise Linux 6, 7 and 8
-
Fedora 30 and 31
-
Gentoo Linux
-
SUSE Linux Enterprise server 12 and 15
-
openSUSE Leap 15.1
-
随着VirtualBox活跃的开发,更快的版本更新,支持的系统和平台越来越多,越来越多的用户选择了它。
1.3. 在Windows上安装VirtualBox
1.3.1. 安装VirtualBox
-
找到刚才下载的 VBOX 安装包并双击运行
-
单击安装界面的 “下一步”
-
根据需要修改安装路径,建议保持默认不修改。然后单击 “下一步”
-
保持默认勾选,直接单击 “下一步”
-
单击 “是” 安装 VBOX 的网络功能
-
直接单击 “安装”
-
自动安装过程一
-
自动安装过程二
-
自动安装过程三
-
自动安装过程四
-
自动安装过程五
-
直接单击 “完成”
-
安装成功后,会自动运行 VBOX 软件,如下图所示:
1.3.2. 安装VirtualBox扩展包
VBOX 的高级功能依赖于扩展包,包括 USB 2.0 和 USB 3.0 设备,VirtualBox 远程桌面,硬盘加密,NVMe(M2)固态硬盘等。
-
双击运行扩展包安装程序
-
单击弹出窗口上的 “安装”
-
拖动许可协议窗口右边滚动栏,拉到底部(重要!!!!!!)
-
拉到底部之后,灰色不可用的 “我同意” 按钮变为可点击。然后,单击 “我同意”
-
一切顺利的话,很快就能看到成功安装的提示框
至此,VBOX 基础软件和扩展包已经安装完毕。
1.4. 创建第一个虚拟机
我前面提过,本教程使用 CentOS7(Linux发行版)作为系统平台。
根据下面的提示创建第一个(CentOS7)虚拟机。
1.4.1. 创建虚拟机
-
打开 VBOX 软件,在界面上单击 “新建” 按钮
-
修改 “新建虚拟电脑” 中的 “名称”,这里我以 “CentOS7” 为例。至于 “文件夹”,建议新手默认,高级用户随意。其它设置保持默认,新手请勿修改。
-
出于个人习惯,我将 “文件夹” 指定到了
D
盘
-
同样根据个人需要自行修改
vdi
文件位置,新手默认。第一个虚拟机 “文件大小” 直接默认8G就虚拟机文件行,其余全部默认。然后,单击 “创建”
-
创建完成
1.4.2. 设置虚拟机
根据教程内容,你需要设置光驱加载ISO文件和桥接网卡。
-
注意下图中的 “[光驱] 没有盘片” 和 “网络地址转换(NAT)” ,单击 “设置”
-
弹出默认虚拟机设置
-
找到 “存储” 中的 “控制器:IDE”
-
单击 “分配光驱” 后面的光盘图标
-
选择 “Choose a disk file…”
-
找到提前下载好的ISO文件并单击,然后单击 “打开”
-
设置效果,如图所示:
-
不过,我们还需要修改开机启动顺序,设置为开机光驱启动。选择 “第一IDE控制器主通道”
-
最终设置,如下图所示:
-
接下来设置网卡,单击左侧的 “网络”
-
单击 “连接方式(A)”
-
选择列表中的第二个,即 “桥接网卡”
-
界面名称保持默认,不要改动。否则可能导致网络不同。
-
设置完毕,如图所示:
-
单击 “OK”,回到软件主界面,光驱和网卡对应的文字已经发生变化。
1.5. 在虚拟机中安装CentOS(上)
通常, |
1.5.1. 开始
|
|
-
打开 VBOX 软件界面,选中左侧的 “CentOS7” ,然后单击 “启动”
-
虚拟机 “电源” 通电后,你会看到如下界面
-
单击右上角的蓝色 ,关闭提示
-
关闭提示后,如图所示:
-
单击黑色背景区域,让鼠标被虚拟机捕获。这时,你可以使用键盘 箭头选择菜单中的 “Install CentOS 7”
-
敲 Enter,启动安装过程
-
等待启动完成,通常需要20秒左右
1.5.2. 安装(上)—— 基本参数设置
|
|
-
CentOS 7 安装界面——欢迎界面
-
单击右上角的蓝色 ,关闭提示
-
单击虚拟机屏幕,输入英文 “chinese” ,正上方会出现你要找的 “中文”
-
选择 “中文” → “简体中文(中国)” ,然后单击 “继续”
-
CentOS 7 安装界面——安装信息摘要。稍等一会儿,下方灰色区域会变为可操作
-
如图所示:
-
向下拖动右边 隐藏 的滚动条,或使用鼠标滚轮向下拖动
-
找到 “系统” → “安装位置”
问:为什么不使用自动分区? 答: 如果你能hold住,欢迎尝试LVM。 |
1.5.3. 安装(上)—— 设置分区
|
|
-
单击 “安装位置”
-
“设备选择” 能看到之前配置的8G硬盘,保持勾选状态。
-
单击 “我要配置分区”
-
然后,单击 “完成” 按钮
-
会自动弹出 “手动分区” 界面
-
单击 “新挂载点将使用以下分区方案” 下的列表,选择 “标准分区”
-
然后,单击上方的 “点这里自动创建他们”
-
系统帮助你创建的分区如下:
-
这里没什么要修改,直接单击 “完成”
-
弹出 “更改摘要”
-
选择 “接受更改”
1.5.4. 安装(上)—— 网络设置
|
|
-
分区设置完毕,又回到了欢迎界面。然后,单击 “网络和主机名” ,设置网络参数
-
如图所示:
-
将右边的网络开关按钮切换至 “打开” 。网络如果正常,旁边会显示IP地址信息。
-
至于主机名看个人心情设置
主机名只能使用英文字母、数字、下划线和点,长度不能超过30个字符 |
-
网络参数设置完毕,单击 “完成”
-
回到欢迎界面,可以看到网络已经连接
1.6. 在虚拟机中安装CentOS(下)
-
所有安装参数已经设置完毕,单击 “开始安装” 继续安装
-
安装进行中,这时单击 “ROOT 密码” ,设置
root
用户密码
-
第一次装虚拟机密码请尽量简单,方便记忆
-
比如,你可以设置为
12345678
云服务器、云数据库等任何连接到互联网的系统或服务,请保证密码足够安全。123456 、admin 等这种密码是绝对不安全的。
|
-
第二次输入密码
-
单击 “完成” 。如果你的密码少于六位数,必须 单击两次 才能设置成功,可以忽略 黄色警告 提示
-
安装进行中
-
安装进行中
-
安装完成
-
单击 “重启” 按钮
“重启” 操作只对虚拟机有效,不会重启你的 Windows。 |
1.7. 启动CentOS
-
执行重启后,虚拟机会忽略之前设置的光驱启动,直接从刚才安装的 “CentOS7” 启动
-
启动完成,进入登录界面
-
单击虚拟机屏幕,进入虚拟机并输入用户名
root
,密码12345678
,然后按 Enter。如果登录失败,会再次提示输入用户名和密码。
输入密码时,为了安全,系统不会在屏幕上显示密码或星号。不要为 “Password” 后面不显示而困扰。 |
-
进入系统后,执行命令
ip a
查看IP地址(192.168.2.236
)。请记住这个地址,下一章你需要使用客户端工具,通过网络连接CentOS7。
2. 客户端工具
- 你需要了解这些
-
-
通常支持客户端工具的工具,我们统称为
客户端工具
; -
Linux(如之前安装的
CentOS 7
)上自带客户端工具(Linux终端)。
-
2.1. 客户端工具介绍
2.1.1. 图形界面工具
Linux社区有许多免费的图形化连接工具,足够日常使用,不需要使用收费软件,也没必要使用破解软件。比如Xshell、SecureCRT等。 |
Putty(开源)
迷你版的连接工具,欠缺方便的标签管理功能,每次连接远程主机比较麻烦。
不推荐作为主力工具使用。
MobaXterm(免费版)
强烈推荐Windows用户使用
主要特性
-
支持Linux(SSH)、telnet、VNC、Windows(RDP)连接;
-
支持X11-Forwarding;
-
自动SFTP浏览支持;
-
最多保存12个服务器标签(session);
-
最多同时建立两个连接隧道。
2.1.2. 命令行工具
WSL终端
WSL是Windows 10上的迷你Ubuntu系统,能够运行几乎所有Linux命令,没有图形界面。可以把WSL看做运行在Windows 10系统下的Linux终端。
如果你使用Windows 10做主力系统,又能接受没图形界面,请移步 客户端工具之Linux终端 。
2.1.3. 最后
现在,我开始介绍Windows下好用、功能丰富又免费的MobaXterm。
2.2. MobaXterm安装
2.2.1. 下载
2.2.2. 安装
解压下载的文件 MobaXterm_Installer_v12.4.zip
,双击运行解压后的 MobaXterm_Installer_v12.4.msi
。
MobaXterm和大多数Windows软件一样,都使用安装向导。当你准备好之后,单击 Next 按钮。
同意软件用户协议,勾选 " I accept the terms in the License Agreement"
,继续安装。
软件安装位置,保持默认即可。
单击 Install 开始安装。
MobaXterm安装完成。
2.2.3. 运行
安装后,可以在开始菜单中找到MobaXterm。
桌面上也有MobaXterm快捷方式,双击MobaXterm图标,运行看看。
2.2.4. 最后
你也看见了,MobaXterm启动后是英文界面。
可能有人正在百度搜索 "MobaXterm中文破解版"
、"MobaXterm中文绿色版"
。
MobaXterm不支持中文 ,你也不需要中文,不要高估自己的需求。
照猫画虎,跟着我学会日常使用。
2.3. MobaXterm连接远程主机
MobaXterm把连接称为Session,每个连接对应一个Session,在Session中可以配置连接参数(IP地址、端口、帐号、密码、私钥等)。
"连接" 在这里是名词,表示从你电脑到远程主机之间的一个网络连接。连接是你和远程主机的一个通道,通道拥有地址(IP地址)、车道(端口)、车牌号(帐号)等等属性。
|
单击 Session 按钮,创建一个连接。
选择 SSH 按钮。
这时,你可以看到 "Basic SSH settings"
标签,包含连接的基本信息。
|
"Remote Host"
中输入远程主机IP地址(192.168.2.236)。
不知道自己虚拟机IP地址? 请参考“准备VirtualBox虚拟机”→“1.7. 启动CentOS”查看远程主机IP地址。 |
勾选 " Specify username"
。
输入用户名:root,单击 OK 按钮连接远程主机。
在黑色窗口中,输入远程主机密码,然后按 Enter 键。
输入密码时,屏幕上不会显示密码。 |
MobaXterm会提示是否保存远程主机密码。勾选 " Do not show this message again"
,按 Yes 按钮保存密码。
一切顺利的话,你可以看到下面这样的提示信息。
也许你好奇左边的目录是什么? 下一小节会介绍简单使用,更多的会在第三章中介绍。 |
2.4. MobaXterm设置无密码登录
2.4.1. 选择?
MobaXterm有记住密码功能,连接远程主机不会提示密码,使用方便。
这对大多数人来说已经足够,对无密码登录(密钥登录)没有需要,请跳过本节内容。
如果你有以下情况,建议开始阅读以下内容:
-
远程主机未开启密码登录支持,仅支持密钥登录;
-
可能存在多终端设备(如Windows、Mac、手机等)连接远程主机的情况;
-
重视个人隐私,不希望有软件记录远程主机密码。
我笔记本的主力系统是Archlinux,写文案偶尔会切换到Windows系统。外出使用安卓手机的 JuiceSSH 终端。没有密钥登录,我简直寸步难行。想想远程主机的超长随机密码…… |
本节操作步骤较多,慢慢操作,不要 "迷路" 。
|
2.4.2. 密钥对介绍
密码不方便记忆,有时候为了安全设置长密码让问题更凸显,也有时候是因为远程主机太多。
我个人的习惯是第一次登录之后立刻设置无密码登录,业内大家更喜欢称为密钥登录。
如果你是第一次使用无密码登录,需要生成密钥对。密钥对生成后,可以重复使用,不需要每次生成。我的远程主机使用密钥对已经超过十年。
如果你有密钥对,直接上传公钥(锁)到远程主机,使用私钥(钥匙)可以登录远程主机。不用再生成密钥对。
在开始之前,需要说明一下。
密钥对包括两个文件:私钥文件(Private Key),公钥文件(Public Key)。
私钥文件 |
相当于门钥匙,作为登录远程主机的关键。 |
公钥文件 |
相当于门锁,只要有钥匙就可以打开。公钥文件可以发布到任何地方,不需要保密。 |
私钥文件不能外泄,否则远程主机有严重的安全风险。
2.4.3. 生成密钥对
生成密钥对
MobaXterm的 "Tools"
中包含很多实用工具,也包含了密钥生成工具。
单击
,打开操作界面。单击 Generate 按钮,开始生成密钥对。
移动鼠标可以产生更多随机数,从而加速过程。
生成需要约一分钟。
密钥对生成完毕。
准备工作
新建名为 "ProLinux"
的文件夹,用来保存公钥文件和私钥文件。
如,我在 D:
盘新建文件夹 "ProLinux"
:
如何新建文件夹? |
最终,我的文件夹绝对路径为:
"D:\ProLinux"
保存公钥
配置无密码登录不能直接用 Save public key 功能保存公钥,必须直接复制公钥内容才行。 具体操作见下文。 |
复制下图文本框中的所有内容:
双击进入 "ProLinux"
文件夹 → 新建一个 "文本文档"
→ 文件名设置为 "mk.pub"
:
怎样新建文本文档? 在 "mk.pub" 文件上,单击
|
最后,用记事本打开 "mk.pub"
文件 → 粘贴公钥内容 → 按 Ctrl+S 保存:
怎样用记事本打开? |
保存私钥
单击 Save private key 按钮,开始保存 私钥文件 操作。
未设置私钥密码,MobaXterm会弹出警告,选择 是(Y) 忽略之。
私钥密码相当于再给锁上加锁,更安全。即便遗失,也不用担心。连接远程主机时,必须输入密码才能使用私钥。 |
普通人不需要这样的安全等级,不需要设置私钥密码。 |
进入刚才创建的 "ProLinux"
文件夹,在 "文件名(N):"
中填写私钥文件名,此处以 mk
为例。单击 保存(S) 按钮,保存文件。
保存类型(T) 默认是 "*.ppk" ,最终私钥文件名为 "mk.ppk" 。
|
查看密钥文件
按照步骤操作完毕后,会得到两个文件:
mk.pub |
公钥文件,必须上传到远程主机(详情见下一小节)。 |
mk.ppk |
私钥文件,在MobaXterm的Session属性中启用之后,连接远程主机生效(详情见下一小节)。 |
2.4.4. 上传公钥
为降低难度,不打算让你 编辑文件,不管是 本地 还是 远程主机 上。
在准备好配置文件之后,让你用鼠标操作完成设置,简单直接。
设置完成后,在远程主机上的 ~/.ssh/authorized_keys
文件中会包含你的公钥。
准备authorized_keys文件
选中 "mk.pub"
按 Ctrl+C 复制文件。
然后,直接按 Ctrl+V 粘贴文件,如图中的 "mk - 副本.pub"
。
选中文件 "mk - 副本.pub"
,按 F2 重命名文件名为 "authorized_keys"
。
双击浏览器中的文字会直接选中,按 Ctrl+C 复制即可,比如上面的 "authorized_keys" 。
|
接着你会看见下面这个提示,选择 是(Y)。
配置文件准备好了。
上传公钥
双击
连接远程主机。下图左边的内容被称为目录树,可以用鼠标操作或编辑文件。
单击 "/root/"
上方中间的黄色 图标,
创建名为 ".ssh"
的隐藏文件夹。
Linux系统中,以点 "." 开头的文件或文件夹均为隐藏文件。 ls 命令查看时,需要带参数 a ,这样:ls -a 。
|
结果如图所示,然后双击进入 ".ssh"
文件夹。
接着单击浅蓝色向上箭头 图标上传文件。
在弹出的选择框中,找到 "Prolinux"
文件夹下的 "authorized_keys"
文件,双击选择。
上传成功后,在目录树中会看到 "authorized_keys"
。
先不要关闭连接标签,接着配置SELinux。 |
关闭SELinux
SELinux功能过于复杂,关闭之是最好选择。否则,无密码登录将会失败。 |
在已经打开的连接标签中,复制下面三条命令,粘贴到黑色窗口中,然后敲回车执行:
echo SELINUX=disabled>/etc/selinux/config
echo SELINUXTYPE=targeted>>/etc/selinux/config
reboot
执行成功后,CentOS系统会被重启。等待重启成功后,可以继续后面的操作。
2.4.5. 启用私钥
选择
编辑远程主机配置参数。弹出设置界面:
选择 "Advanced SSH settings"
标签,找到 "User private key"
参数,单击输入框尾部的文件 图标。
弹出文件选择框,双击私钥文件 "mk.ppk"
。
设置效果如图所示,单击 OK 保存配置。
2.4.6. 测试无密码登录
启用私钥后,必须关闭连接。重新连接远程主机,才能确认私钥是否有效。 |
在MobaXterm主界面双击
,测试连接远程主机。如果登录成功,说明密钥设置没问题。
3. 传输文件
本章内容是为有传输文件需求的你准备的,可以先跳过。等你准备好时,再来实践学习。
打开你的MobaXterm,连接上远程主机,开始练习……
3.1. 用MobaXterm上传下载文件
3.1.1. 准备文件
为减少操作步骤,我会使用 Windows终端
简称(终端)创建文件。
打开Windows终端
在文件资源管理器中打开 D:\ProLinux
,单击地址栏:
输入 "cmd"
,按 Enter 键。
Windows终端
如下图所示:
创建文件
创建目录和文件相关操作都在终端中完成。 |
-
在终端中创建目录,名称为
"files"
:
mkdir files
-
在目录
"files"
下创建名为"foo.txt"
的文件,文件内容为"test text: foo"
:
echo 'test text: foo' > files/foo.txt
-
同样的方式创建
"bar.txt"
echo 'test text: bar' > files/bar.txt
-
查看目录
"files"
下的文件,确认是否创建成功:
dir files
D:\ProLinux>dir files 驱动器 D 中的卷没有标签。 卷的序列号是 B4E5-398C D:\ProLinux\files 的目录 2020/02/26 17:18 <DIR> . 2020/02/26 17:16 <DIR> .. 2020/02/26 17:18 19 bar.txt 2020/02/26 17:17 19 foo.txt 2 个文件 38 字节 2 个目录 240,456,257,536 可用字节
-
关闭终端
-
在文件资源管理器中查看:
3.1.2. 上传文件或目录
登录远程主机之后,直接(按住左键)将 "files"
目录拖拽到MobaXterm左边的目录树:
确认上传
-
方法一:MobaXterm目录树
-
方法二:Linux命令
-
查看
"files"
目录:
-
ls -l ~
[root@prolinux ~]# ls -l total 4 -rw-------. 1 root root 1305 Dec 7 16:31 anaconda-ks.cfg drwxr-xr-x. 2 root root 36 Feb 26 17:42 files
-
查看
"files"
目录下的文件:
ls -l files/
[root@prolinux ~]# ls -l files/ total 8 -rw-r--r--. 1 root root 19 Feb 26 17:42 bar.txt -rw-r--r--. 1 root root 19 Feb 26 17:42 foo.txt
屏幕截图:
3.1.3. 下载文件或目录
下载和上传方法都是一样的,直接把MobaXterm目录树中显示的文件或目录拖拽到本地就行了。
- 上传
-
MobaXterm目录树 Windows文件资源管理器
- 下载
-
Windows文件资源管理器 MobaXterm目录树
4. 文件、目录与路径
本章使用Gnome桌面+Linux终端完成演示效果
4.1. 什么是文件
Linux以文件的形式储存数据,常见的文件有图片、Word文档、PPT、PDF等等。
常以名称、大小来描述一个文件。
如下图所示:
4.1.1. 文件名称
上图的 "pic10"
是 名称 ,".jpg"
是 扩展名 ,合在一起就是完整的文件名称 "pic10.jpg"
。
什么是文件名称?
呃呃呃…就是一个名字(dog脸)。
为什么你知道 "pic10.jpg"
是一个图片文件,"book.pdf"
是一个PDF文件?
还不是因为扩展名。
那在Linux中扩展名有什么用呢?
小声告诉你~
其实没用,只为好看而已。
在Windows中,文件扩展名决定了Windows会用哪个软件打开。 |
最后要强调一下:
文件名称甚至扩展名只是一个名字,文件名称不影响文件内容或文件类型。
4.1.2. 文件大小
上面这个截图说,"pic10.jpg"
文件大小为 "72.3KB"
或 "72,322 字节"
。
文件大小的基本度量单位是 byte
(字节)。
大文件用字节表示时太长,可以用千字节(KiB/kB)、兆(MiB/MB)、吉(GiB/GB)、太(Tib/TB)来表示。
“为什么有Kib,又有KB?有什么不同?”
“因为采用的度量标准不同,Kib是用2的整数次幂计算(二进制乘数词头标准),kB是用10的整数次幂计算(国际单位制词头标准)。”
“全部用byte(字节)表示就没这个问题(机智),就是太长(微笑)。”
举栗子,
“1. 我要换个头像,这张200kB的看起还将就~”
200kB = 200千字节 = 200 * 10的3次方字节 = 200000byte
“2. 新买的手机拍照效果很好,照片分辨率2592x3840,每张大概4MB、5MB的样子。”
4MB = 4兆 = 4 * 10的6次方字节 = 4000000byte
“3. 下了部加长版的阿凡达,1080P版本的,有42.5GB大。”
42.5GB = 42.5吉 = 42.5 * 10的9次方字节 = 42500000000byte
“4. 买了个2TB的希捷硬盘,用来放实验数据。”
2TB = 2太 = 2 * 10的12次方字节 = 2000000000000byte
“5. 在Linux终端下,用 『du -sh』命令统计Downloads目录下有15GiB的文件。”
15GiB = 15吉 = 15 * 2的30次方字节 = 16106127360byte
是不是已经凌乱了?确实,Linux、Windows、Mac以及各种软件都没有统一的度量标准这点让人头痛。
另外一个常见栗子:
“买了2T的硬盘,插到电脑上,只显示1.8T。奸商~”
“到底硬盘厂家是不是奸商呢?”
“因为计算容量的标准不同,硬盘厂家用10的整数次幂计算,你的电脑用的2的整数次幂计算。所以,硬盘容量最终是有差距。”
为了美好的生活,你只需要记住:
Windows、Linux终端使用二进制乘数词头计算文件大小,Linux桌面软件(比如,Gnome)、硬盘厂家则使用国际单位制词头。
4.1.3. 空文件
大小为0或没内容的文件,称作 空文件。
4.2. 什么是目录(文件夹)
目录相当于一个容器,将多个文件或其它目录存储在一起。
Linux系统包含成千上万个目录。
多个文件通过存储在一个目录中,可以达到有组织的存储文件的目的。
在一个目录中的另一个目录被称作它的子目录(子文件夹)。这样,这些目录就构成了树状网络,或目录树。
上面这个目录树有5个子目录和34个文件。
4.2.1. 目录还是文件?
在桌面中,你一眼就分辨出目录和文件了对吗?
那现在呢?
“这题我会~”
“蓝色 的是目录,白色 的是文件。”
“ohhhhh~”
友情提示,颜 色 可 是 会 变 的 哦?
换个直观的办法:
看到第一二行的第一列没,都是 drwxrwxr-x.
。第一个字母 d 是英文directory的缩写,有它出现的地方就是目录啦~
那文件呢? -
(中横线)开头的就是文件。
其实,我也是经常用颜色区分的,主要还是方便~哈哈 |
关于目录名称的迷惑
我创建了一个目录 "pic123456.jpg"
。它是这个样子:
“没问题呀!”
那这样呢?
“看起来像图片文件对不对?”
“它…还是目录哦~”
和之前一样,用 颜色 或者字母 d 可以分辨出来。
4.2.2. 空目录
目录下没有文件或子目录,同样称作 空目录。
4.3. 什么是路径
路径表示文件或目录在Linux系统的位置,就像经纬度能够标示地球上的任何一个位置一样,防迷路。
各种路径:
-
/home/mk/Downloads/templated-radius/
-
/usr/share/zoneinfo/
-
/var/log/
-
/usr/share/zoneinfo/Asia/Shanghai
-
../zoneinfo/Asia/Shanghai
-
/home/mk/Downloads/templated-radius/images/pic10.jpg
-
images/pic10.jpg
-
/home/mk/Downloads/templated-radius/assets/css/main.css
-
assets/css/main.css
-
../../assets/css/main.css
路径以斜线(/)分隔,以文件名称或目录名称结尾。
我之前用树状结构(目录树)表示了文件和目录的关系。
现在,你会发现路径看起来像一条直线,更加直接。
为更精确表达,路径以文件名称结尾,称作文件路径。反之称作目录(文件夹)路径。
路径以斜线结尾(如,/var/log/
)的,一定是目录(文件夹)路径。
路径太长时,用起来不方便。
Linux又有绝对路径和相对路径之分。
绝对路径太长时,用相对路径代替很方便。
接下来两小节,会详细介绍绝对路径和相对路径。
喜欢编程的小伙伴,在路径问题上踩过不少坑。还没踩坑的话,一定要看看下面两个小节哦~ |
4.4. 绝对路径
绝对路径以根目录(/)开头,不会因当前位置(工作目录)而变化。
|
绝对路径例子:
-
/home/mk/Downloads/templated-radius/ ← 目录
-
/usr/share/zoneinfo/ ← 目录
-
/var/log/ ← 目录
-
/usr/share/zoneinfo/Asia/Shanghai ← 文件
-
/home/mk/Downloads/templated-radius/images/pic10.jpg ← 文件
-
/home/mk/Downloads/templated-radius/assets/css/main.css ← 文件
无法确定是文件路径还是目录路径时,可以使用 ls -l 或 file 命令查看,比如 file /usr/share/zoneinfo/Asia/Shanghai 。
|
绝对路径组成示例:
4.5. 相对路径
相对路径是以当前目录(工作目录)为前提,使用 简短的路径 代替 绝对路径。
相对路径可能以 "./" 或 "../" 开头。一个点表示当前位置,连续两个点表示上级目录。当以 "./" 开头时,可以被省略。
由于当前目录随时在变化,可能导致文件或目录明明 存在,却 找不到 的情况。
建议:
在终端中手动操作文件或目录时使用相对路径,其它情况下使用绝对路径。
为什么手动操作时用相对路径呢? 因为打字少!
看看这两个绝对路径:
-
/usr/bin
-
/usr/bin/cat
用相对路径表示:
-
../bin
、./bin
、bin
、bin/
-
./bin/cat
、bin/cat
、./cat
相对路径是否有效,取决于工作目录。
下面我以命令行和树状网络为例,详细说明:什么是相对路径?
4.5.1. 绝对路径与相对路径的转换:命令行
连接远程主机,跟我做:
-
../bin
、./bin
、bin
、bin/
[mk@archlinux ~]$ ls -dl /usr/bin drwxr-xr-x 7 root root 135168 2月 24 10:07 /usr/bin [mk@archlinux ~]$ cd /usr/include/ [mk@archlinux include]$ ls -dl ../bin drwxr-xr-x 7 root root 135168 2月 24 10:07 ../bin [mk@archlinux ~]$ cd /usr [mk@archlinux usr]$ ls -dl ./bin drwxr-xr-x 7 root root 135168 2月 24 10:07 ./bin [mk@archlinux usr]$ ls -dl bin drwxr-xr-x 7 root root 135168 2月 24 10:07 bin [mk@archlinux usr]$ ls -dl bin/ drwxr-xr-x 7 root root 135168 2月 24 10:07 bin/
-
./bin/cat
、bin/cat
、./cat
[mk@archlinux ~]$ ls -l /usr/bin/cat -rwxr-xr-x 1 root root 39048 11月 12 19:00 /usr/bin/cat [mk@archlinux ~]$ cd /usr/ [mk@archlinux usr]$ ls -l ./bin/cat -rwxr-xr-x 1 root root 39048 11月 12 19:00 ./bin/cat [mk@archlinux usr]$ ls -l bin/cat -rwxr-xr-x 1 root root 39048 11月 12 19:00 bin/cat [mk@archlinux usr]$ cd bin [mk@archlinux bin]$ ls -l ./cat -rwxr-xr-x 1 root root 39048 11月 12 19:00 ./cat
4.5.2. 绝对路径与相对路径的转换:树状网络
工作目录:/usr/bin
绝对路径:/usr/bin/cat
相对路径:./cat
4.5.3. 树状网络、绝对路径及相对路径一览表
工作目录:/usr/include/ |
||
---|---|---|
绝对路径 |
相对路径 |
说明 |
/usr/include/ |
.(一个点) |
绝对路径和当前目录( |
/usr/include/pwd.h |
./pwd.h 或者 pwd.h |
当前目录( |
/usr/include/linux/nfc.h |
./linux/nfc.h 或者 linux/nfc.h |
当前目录( |
/usr/lib/ |
../lib/ |
上级目录 |
4.5.4. 总结
通过上面的这么多例子相信你注意到了一个规律:如果文件路径没有以 /
开头,那它是相对路径。
以此类推,假如我有文件名为 my.png
的文件,执行命令:
ls my.png
那上面的 my.png
会被命令视作相对路径,等同于 ./my.png
。
另外一个规律:如果将文件名作为参数用在命令行或软件中时,会被当作文件(相对)路径。同理,目录名称做参数时,情况相同。
4.6. 关于文件那些事儿
-
区分大小写
-
不关心扩展名
-
隐藏文件:以
"."
开头的文件或目录
4.6.1. Linux区分大小写
这非常重要,也是Linux萌新常见问题的来源。
比如,我用Linux搭建了网站,有网页文件 "home.html"
,访问网址为:
一般情况下,访问 http://www.xquickstartguide.com/prolinux/test/HOME.html 会看到 "网页无法找到"
的错误提示。
大写的 "HOME.html"
文件实际是不存在的。
在Windows系统中,就没有 "HOME.html"
这样的问题。因为,Windows系统不区分大小写。
就日常使用来说,在Linux系统中可以创建两个或多个名字相同的文件和目录,只要大小写字母是不同的就行。如,foo.txt、FOO.txt、foo.TXT是三个同名文件。在Windows系统中创建 foo.txt 之后,创建文件 FOO.txt 会提示错误。
4.6.2. Linux不关心扩展(名)
在 [什么是文件] 一节中提过扩展(名),也许你之前难以理解。从这里开始,扩展名将变得更加具体。
扩展(名)一般由2到4个字符组成,用来表示文件类型。以下是常见扩展:
foo.exe |
执行文件或程序 |
foo.txt |
文本文件 |
foo.png/bar.gif/quz.jpg |
图片 |
在Windows系统中扩展(名)非常重要,系统以此检测是什么类型的文件。Linux系统实际上会忽略扩展名,通过查看文件内容确定文件类型。比如,我有一个图片文件 my.png
。我把文件重命名为 my.txt
之后,Linux还是会将之看作图片文件。因此,有时候很难确定某个特定文件是什么类型的文件。幸好有 file
的命令,它可以帮助确定文件类型。
file 文件路径
$ file my.txt
my.txt: PNG image data, 4480 x 1440, 8-bit/color RGBA, non-interlaced
现在,你肯定已经知道 "my.txt" 是 "./my.txt" 的简单用法。在 <相对路径_总结> 内容中已经说过,命令行中指定一个文件或目录(如 "my.txt" )时,实际上会被视作文件路径("./my.txt" )。
|
4.6.3. 隐藏文件
隐藏文件
在Linux系统中,任何以 "."
(点)开头的文件是隐藏文件。默认情况下,不显示。比如,
# ls -l ~
总用量 4
-rw-------. 1 root root 948 8月 27 2019 anaconda-ks.cfg
用 ls
命令只看到一个名为 "anaconda-ks.cfg"
的文件。
使用 -a
参数再试一次呢?
# ls -al ~
总用量 52
dr-xr-x---. 4 root root 4096 8月 27 2019 .
dr-xr-xr-x. 17 root root 4096 8月 27 2019 ..
-rw-------. 1 root root 948 8月 27 2019 anaconda-ks.cfg
-rw-------. 1 root root 8403 8月 27 2019 .bash_history
-rw-r--r--. 1 root root 18 12月 29 2013 .bash_logout
-rw-r--r--. 1 root root 176 12月 29 2013 .bash_profile
-rw-r--r--. 1 root root 176 12月 29 2013 .bashrc
-rw-r--r--. 1 root root 100 12月 29 2013 .cshrc
drwxr-xr-x 4 root root 48 8月 27 2019 .kube
drwxr-----. 3 root root 18 8月 27 2019 .pki
-rw-r--r--. 1 root root 129 12月 29 2013 .tcshrc
-rw------- 1 root root 4243 8月 27 2019 .viminfo
好,这次用 ls -al
看到 "~"
(/root) 目录下有很多以 "."
开头的文件(隐藏文件)。
隐藏目录
如果目录以 "."
开头就是隐藏目录。是不是很简单?
试一试创建一个隐藏目录:
测试完,记得删除
|
隐藏文件用来做什么
在Linux系统中,大多数软件都有自己的配置文件或者目录。
通常,全局配置文件会放在 "/etc"
目录下,用 ls
直接可见。
用户配置文件则放在 "~"
(用户家目录)下,都是隐藏文件,用 ls -a
才能看见。
家目录下的配置文件多数是软件自动创建,隐藏起来显得更清爽。
5. 文件和目录管理
在开始本章之前,你要明白一件事情:对于Linux系统来说,一切都是 "文件"
。文本、目录、你的键盘和鼠标等等都是 "文件"
。可能有些意外,不过这不影响什么。但,请记住这一点,因为它有助于理解Linux命令的行为。
本章有较多命令输入,请使用 Tab 键补全文件名,更方便。 怎么使用补全快捷键? 比如,你要执行命令 输入 如果有多个相同字母开头的文件名,Tab 键补连续按两下,操作方法:
按 Tab 键的动作,只要你需要可以按无数次,特别是在文件名特别长的时候。 |
5.1. 在目录之间切换
cd
命令:在目录之间切换
5.1.1. 基础用法
cd 目录路径
- 参数
--help |
查看帮助信息 |
5.1.2. 常用路径符号
"."
|
当前目录 |
".."
|
上级目录 |
"~"
|
家目录,root用户家目录为 |
5.1.3. 操作演示
绝对路径
|
[root@prolinux ~]# cd /usr
[root@prolinux usr]#
相对路径
|
[root@prolinux usr]# cd local/bin
[root@prolinux bin]#
或者
[root@prolinux usr]# cd ./local/bin
[root@prolinux bin]#
当前目录
|
[root@prolinux bin]# cd .
[root@prolinux bin]#
看见了吧?
"."
没什么用,忘掉最好~
上级目录
|
[root@prolinux bin]# cd ..
[root@prolinux local]#
家目录
|
[root@prolinux local]# cd ~
[root@prolinux ~]#
偷懒的写法是,不要 "~"
,直接 cd
→ Enter,不加参数。
想试一试?
没问题…
先随便切换一个目录,比如 "/usr/local"
:
[root@prolinux ~]# cd /usr/local
[root@prolinux local]#
然后:
[root@prolinux local]# cd
[root@prolinux ~]#
5.2. 创建文件
5.2.1. 文件
创建空文件
创建一个空文件,如果文件已经存在,则会修改文件最后一次更新时间:
touch foo.txt
touch 命令本来用于修改文件时间。只是修改过程中,如果文件不存在,它会创建一个空文件。你就是利用这个特点创建的文件。
|
创建带内容的文件
有时,在创建文件之前,脑子里已经确定了内容,可以这样:
echo "这是测试文本。" > foo.txt
如果 foo.txt 文件已经存在,上面的命令会清空文件内容哦!
|
如果 foo.txt
文件已经存在,使用两个连续的大于符号( >>
)可以追加一行或多行到文件最后。
echo "这是测试文本1。" >> foo.txt
echo "这是测试文本2。" >> foo.txt
最终,foo.txt
内容是这样:
这是测试文本。 这是测试文本1。 这是测试文本2。
5.2.2. 目录
创建目录,如果目录已经存在会报错,不用管:
mkdir ProLinux
有时,你会创建这样的目录 ProLinux/files/2020_03_03
。创建多级目录也很简单,加参数 -p
就行:
mkdir -p ProLinux/files/2020_03_03
如果父目录 ProLinux
不存在,也能创建成功。同理,files
目录不存在也行。也就是说,路径中的所有子目录如果不存在,都会被创建。
划重点,-p
参数要考(滑稽)。
相对路径
|
5.3. 列表目录
5.3.1. 查看目录
每次在终端上操作,你都需要确认你在哪个位置(工作目录或当前目录),才不至于 迷路
。
刚好,pwd
命令可以帮到你:
[root@prolinux ~]# pwd /root
好的,你现在处于 /root
目录。执行 ls
命令,可以直接看到本目录下内容:
ls 命令不加参数时,会直接查看当前目录下的内容。
|
也可以使用 ls . 命令,前者只是省略了(相对)路径参数。
|
[root@prolinux ~]# ls files ProLinux [root@prolinux ~]# ls . files ProLinux
你要明白,上面的方法不是唯一的方法。也可以查看绝对路径下的目录内容:
ls /root/
[root@prolinux ~]# ls /root/ files ProLinux
ls ..
可以查看上级目录:
[root@prolinux ~]# ls .. bin dev home lib64 mnt proc run srv tmp var boot etc lib media opt root sbin sys usr
也可以指定更加复杂的相对路径:
ls ../usr/src/
[root@prolinux ~]# ls ../usr/src/ debug kernels
当然,也可以查看当前目录下的子目录内容:
ls files/
[root@prolinux ~]# ls files/ bar.txt foo.txt
查看隐藏文件
凡是以 .
开头的文件或目录,都称为隐藏文件或目录。配合 -a
参数可以看到:
[root@prolinux ~]# ls -a . .bash_history .bash_profile .cache .cshrc .lesshst ProLinux .tcshrc .. .bash_logout .bashrc .config files .pki .ssh .viminfo
5.3.2. 列出更多信息
有时,你需要知道文件的修改时间或者权限。ls -l
或 ll
命令会以列表的方式,将文件信息打印到屏幕上。
ll 是 ls -l 的命令快捷式,两者没有区别。
|
[root@prolinux ~]# ls -l total 0 drwxr-xr-x. 2 root root 36 Mar 3 19:21 files drwxr-xr-x. 2 root root 36 Feb 26 15:10 ProLinux [root@prolinux ~]# ll total 0 drwxr-xr-x. 2 root root 36 Mar 3 19:21 files drwxr-xr-x. 2 root root 36 Feb 26 15:10 ProLinux
查看隐藏文件
和之前一样,加 -a
参数配合使用。
[root@prolinux ~]# ls -al 总用量 52 dr-xr-x---. 4 root root 4096 8月 27 2019 . dr-xr-xr-x. 17 root root 4096 8月 27 2019 .. -rw-------. 1 root root 948 8月 27 2019 anaconda-ks.cfg -rw-------. 1 root root 8403 8月 27 2019 .bash_history -rw-r--r--. 1 root root 18 12月 29 2013 .bash_logout -rw-r--r--. 1 root root 176 12月 29 2013 .bash_profile -rw-r--r--. 1 root root 176 12月 29 2013 .bashrc -rw-r--r--. 1 root root 100 12月 29 2013 .cshrc drwxr-xr-x 4 root root 48 8月 27 2019 .kube drwxr-----. 3 root root 18 8月 27 2019 .pki -rw-r--r--. 1 root root 129 12月 29 2013 .tcshrc -rw------- 1 root root 4243 8月 27 2019 .viminfo
只看目录,不看子目录
[root@prolinux ~]# ls -dl files/ drwxr-xr-x. 2 root root 36 Mar 3 19:21 files/
查看内容,包括子目录
[root@prolinux ~]# ls -R .: files ProLinux ./files: bar.txt foo.txt ./ProLinux: bar.txt foo.txt
加上 -l
参数,文件信息更详细。
[root@prolinux ~]# ls -Rl .: total 0 drwxr-xr-x. 2 root root 36 Mar 3 19:21 files drwxr-xr-x. 2 root root 36 Feb 26 15:10 ProLinux ./files: total 8 -rw-r----r----. 1 root root 19 Mar 3 19:21 bar.txt -rw-r----r----. 1 root root 19 Mar 3 19:21 foo.txt ./ProLinux: total 8 -rw-r----r----. 1 root root 15 Feb 26 15:12 bar.txt -rw-r----r----. 1 root root 15 Feb 26 15:12 foo.txt
5.4. 编辑文件
在Linux服务器环境(非图形界面)下,我更多使用 vim
编辑文件。vim
强大而丰富的功能吸引了很多人,有人愿意花几天小时甚至几周学习 "如何用好vim编辑器"
,并且没有一点怨言。
但是,vim
非常不适合新人。
如果你只是改个数据密码之类的简单需求,花几分钟了解一下 nano
则是更好的选择。
- 为什么不在Windows上改完文件,通过工具上传到服务器?
-
大部分时候,仅仅修改一下数据密码或邮箱,直接用
vim
或nano
之类的命令行编辑器操作就行了。
不想在本地改完了还要操作上传,太麻烦了。
按照惯例,先安装Nano编辑器:
yum install -y nano
5.4.1. 用Nano创建和打开文件
如果你想创建新文件或打开文件,命令是这样:
nano
这样:
nano foo.txt
或者这样:
nano /data/foo.txt
直接指定文件的绝对路径时,文件的父目录必须存在,否则会报错。比如 nano /data/foo.txt 中的 /data 。如果不存在,不要忘了使用 mkdir /data 创建。
|
第二、三种方法也可以用来打开一个已经存在的文件。
请记住,如果你要打开一个不在当前目录的文件,需要像第三个例子一样写明文件的绝对路径或相对路径。
以下是用Nano编辑器打开文件的截图:
如你所见,在编辑器窗口底部有键盘快捷键的提示信息。方便执行一些基本操作,比如复制粘贴文字。退出编辑器和查看帮助的快捷键也都在这里。
5.4.2. 编辑内容
在Nano编辑器中,敲击键盘就能输入内容,Enter 键可以换行。
- 怎么移动光标呢?
-
试一试键盘右下方的上下左右箭头按键。
- 我从其它地方复制了文字,怎么粘贴进Nano编辑框?
-
鼠标右键,找到粘贴功能(常见
"粘贴"
或"paste"
),选中单击。
5.4.3. 在Nano编辑器中保存文件
保存文件的快捷键是 Ctrl+o (不要按错了哦!是字母o)。当你按了快捷键,编辑器会询问保存文件名称(或确认文件名称)。文件名称设置完毕,按 Enter 键保存文件。
保存文件操作截图:
保存完毕后,按 Ctrl+x 可以退出。
在没保存的情况下,直接按 Ctrl+x,然后输入文件名称,一步完成保存退出操作。是不是更快呢? |
5.4.4. 总结
关于Nano编辑器的基本使用就讲到这里。如果有更加复杂的操作,在Windows上改完再上传是更快的办法。
用Nano本就是图简单,花半个小时学这个就不值得了。
5.5. 打印内容
5.5.1. cat
命令
有时,想把文件所有内容打印到屏幕上:
cat foo.txt
这是测试文本。 这是测试文本1。 这是测试文本2。
也可以打印行号:
cat -n foo.txt
1 这是测试文本。 2 这是测试文本1。 3 这是测试文本2。
5.5.2. less
命令
相较于 cat
命令将文件所有内容打印到屏幕上,less
命令仅仅打印一屏的行为非常奇特。
为什么 less
会这样呢?
在文件内容特别多时,文件内容分批次打印到屏幕才是方便的。不然,所有内容全部打印到屏幕,屏幕至少滚动10秒钟才会停下,我自然也找不到我想要的内容。
5.6. 压缩(打包)和解压文件
5.6.1. 准备测试文件
cd
mkdir -p prolinux
echo "测试文本1" > prolinux/foo.txt
echo "测试文本2" > prolinux/bar.txt
echo "测试文本3" > quz.txt
5.6.2. 压缩(打包)和解压演示
压缩(打包)演示
下文出现的 foo.tar.gz
是相对路径 ./foo.tar.gz
的简化版。根据实际情况,你可以指定任何相对或绝对路径,比如:
-
../foo.tar.gz
-
~/foo.tar.gz
-
/tmp/foo.tar.gz
cd
tar zcvf foo.tar.gz prolinux/ quz.txt
- 解释
zcf |
创建一个压缩包文件 |
v |
显示详细过程 |
foo.tar.gz |
压缩包文件名 |
files/ |
指定加入压缩包的目录,紧跟在压缩包文件名之后 |
quz.txt |
指定加入压缩包的文件,紧跟在压缩包文件名之后 |
压缩包文件名后可以指定多个目录或文件哦!自己动手试试看。 |
查看压缩包内容
tar tf foo.tar.gz
解压演示
解压内容到目录 foo
中:
mkdir -p foo
cd foo
tar xvf ../foo.tar.gz
- 解释
xf |
解压文件 |
v |
显示详细过程 |
foo.tar.gz |
等待解压的(压缩包)文件名 |
说明
尽量将需要打包的目录或文件放到同一个目录下,这样本节演示的压缩和解压方法就是万能的。不再需要学更复杂的操作。作为Linux老司机,我极少遇到解决不了的。
- 如果解决不了怎么办?
-
那我就分别打几个压缩包,这样更快。
5.7. 压缩不同目录下的文件
在你没遇到这个情况的时候,请你跳过本节内容。在需要时,再来看看。 |
5.7.1. 准备测试文件
-
在绝对路径
/tmp
(目录)下创建5个1M的文件,文件内容为随机数据:
mkdir -p /tmp/files
dd if=/dev/urandom bs=1M count=5 of=/tmp/files/tmp_random_file
split -d -b 1M /tmp/files/tmp_random_file /tmp/files/tmp_random_file.
rm -f /tmp/files/tmp_random_file
在 /tmp/files
目录下,会自动生成如下文件:
tmp_random_file.00 tmp_random_file.01 tmp_random_file.02 tmp_random_file.03 tmp_random_file.04
-
在相对路径
prolinux/
(目录)下创建5个1M的文件,文件内容为随机数据:
cd ~
mkdir -p prolinux/
dd if=/dev/urandom bs=1M count=5 of=prolinux/prolinux_random_file
split -d -b 1M prolinux/prolinux_random_file prolinux/prolinux_random_file.
rm -f prolinux/prolinux_random_file
在 ~/prolinux
目录下,会自动生成如下文件:
prolinux_random_file.00 prolinux_random_file.01 prolinux_random_file.02 prolinux_random_file.03 prolinux_random_file.04
5.7.2. 带路径打包
tar zcvf foo.tar.gz /tmp/files
"foo.tar.gz"
内容列表如下:
tmp/files/ tmp/files/tmp_random_file.03 tmp/files/tmp_random_file.01 tmp/files/tmp_random_file.00 tmp/files/tmp_random_file.04 tmp/files/tmp_random_file.02
5.7.3. 不带路径打包
方法一:
cd /tmp/files/
tar zcvf ~/foo.tar.gz tmp_random_file.*
方法二:
tar zcvf ~/foo.tar.gz -C /tmp/files/ tmp_random_file.*
"foo.tar.gz"
内容列表如下:
tmp_random_file.00 tmp_random_file.01 tmp_random_file.02 tmp_random_file.03 tmp_random_file.04
第一种方法逻辑更简单,第二种方法一行搞定。我推荐你在多数情况下使用第一种方法。
5.7.4. 多目录打包
将以下文件打包到压缩文件 foo.tar.gz
:
-
/tmp
下的files
目录及其文件 -
~/prolinux
目录下以prolinux_random_file.
开头的文件
tar zcvf ~/foo.tar.gz -C /tmp/ files/ -C ~/prolinux/ prolinux_random_file.{00..04}
或
tar zcvf ~/foo.tar.gz -C /tmp/ files/ -C ~/prolinux/ .
使用 -C 参数时,不能使用 prolinux_random_file.* 这样的星号通配符。
|
"foo.tar.gz"
内容列表如下:
files/tmp_random_file.00 files/tmp_random_file.01 files/tmp_random_file.02 files/tmp_random_file.03 files/tmp_random_file.04 prolinux_random_file.00 prolinux_random_file.01 prolinux_random_file.02 prolinux_random_file.03 prolinux_random_file.04
5.7.5. 归档文件和压缩文件的区别
-
归档文件只是把多个文件打包放一起,包文件大小更大。
-
压缩文件使用了压缩算法,包文件更小。
创建归档文件:"bar.tar"
,创建压缩文件:"foo.tar.gz"
,
tar vcf ~/bar.tar ~/prolinux
tar zvcf ~/foo.tar.gz ~/prolinux
查看两个文件大小,单位 kb
:
du -sk ~/foo.tar.gz ~/bar.tar
可以明显看出 "foo.tar.gz"
(5124kb) 比 "bar.tar"
(5132kb) 更小:
5124 /root/foo.tar.gz 5132 /root/bar.tar
再看看两个文件类型信息:
file ~/foo.tar.gz ~/bar.tar
"foo.tar.gz"
是 zip
压缩的,"bar.tar"
仅仅是将文件打包。
/root/foo.tar.gz: gzip compressed data, from Unix, last modified: Mon Apr 6 14:48:30 2020 /root/bar.tar: POSIX tar archive (GNU)
5.7.6. 清理测试文件
rm -f ~/foo.tar.gz ~/bar.tar
rm -rf prolinux /tmp/files
5.8. 统计大小
du
命令基本用法: du -sh 目录或文件路径1 [目录或文件路径2] …
,比如:
du -sh foo.tar.gz
5.8.1. 查看文件大小
du -sh ~/foo.tar.gz
58M /root/foo.tar.gz
5.8.2. 统计目录大小
du -sh /usr
1.7G /usr
5.8.3. 统计多个目录大小
du -sh /usr/* /var /tmp
67M /usr/bin 48K /usr/etc 4.0K /usr/games 13M /usr/include 913M /usr/lib 138M /usr/lib64 40M /usr/libexec 169M /usr/local 40M /usr/sbin 291M /usr/share 75M /usr/src 0 /usr/tmp 277M /var 21M /tmp
5.8.4. 其它选择
du
命令不是唯一的选择。你也可以这样查看文件大小:
ls -hl
total 5.1M -rw-r--r-- 1 root root 5.1M Apr 6 17:06 foo.tar.gz drwxr-xr-x 2 root root 4.0K Apr 6 17:06 prolinux
但是,ls -hl
不会统计目录下所有文件的总大小,仅仅显示目录大小为 "4.0K"
。最终,还是 du
命令更香。
5.9. 查看文件类型
在第三章我讲过,文件名或扩展名不决定文件类型。那怎么判断文件类型呢?
file
命令可以检测文件类型。它还会显示文本文件的字符编码,简直是诊断乱码问题的神器。
5.9.1. 准备测试文件
cd
mkdir -p prolinux
touch prolinux/foo.txt
echo 'This is a test text.' > prolinux/bar.txt
echo '这是测试文本。' > prolinux/quz.txt
tar zcf foo.tar.gz prolinux
5.9.2. 运行 file
命令
file
命令基本用法: file 文件路径
,比如:
file prolinux/foo.txt
检测多个文件的类型:
file prolinux/*.txt foo.tar.gz
prolinux/bar.txt: ASCII text prolinux/foo.txt: empty prolinux/quz.txt: UTF-8 Unicode text foo.tar.gz: gzip compressed data, from Unix, last modified: Mon Apr 6 17:06:11 2020
如果你学过HTML,那你一定对这个眼熟:
file -i prolinux/*.txt foo.tar.gz
prolinux/bar.txt: text/plain; charset=us-ascii prolinux/foo.txt: inode/x-empty; charset=binary prolinux/quz.txt: text/plain; charset=utf-8 foo.tar.gz: application/x-gzip; charset=binary
加上 -i
参数,会打印出文件的MIME类型。
5.10. 清空内容
cd
mkdir -p prolinux
echo 'foo123' > prolinux/foo.txt
echo 'bar123' > prolinux/bar.txt
ll prolinux
清空文件内容:
echo > prolinux/foo.txt
或
echo -n '' > prolinux/bar.txt
不加 -n
参数时,"foo.txt"
中有一个换行符(\n
)。看看文件大小:
ls -l prolinux/*.txt
-rw-r--r-- 1 root root 0 Apr 6 17:32 prolinux/bar.txt -rw-r--r-- 1 root root 1 Apr 6 17:32 prolinux/foo.txt
"foo.txt"
大小为1个字节,"bar.txt"
大小为0个字节。
5.10.1. 扩展内容
如果你对换行符有兴趣,可以这样看:
cat -A prolinux/foo.txt
$
上面的美元符号表示换行符(\n
)。
也可以通过查看十六进制确认:
hexdump prolinux/foo.txt
0000000 000a 0000001
上面的 "0a"
是换行符(\n
)的十六进制表示。
5.11. 删除文件
不要在Linux系统上删除任何系统目录(比如 rm -rf / 或 rm -rf /usr 等等)。否则数据丢失,系统崩溃无法启动。
|
rm
命令基本用法:rm 目录或文件路径
,比如:
rm prolinux/foo.txt
rm
在删除前会提示 "remove regular file ‘prolinux/foo.txt’? "
,询问是否删除。
输入 y
,按 Enter 键即可删除。
不想删除了?两种方法:
-
输入
n
,按 Enter 键 -
按 Ctrl+c 键终止操作
如果不想要这个提示,加上 -f
参数:
rm -f prolinux/foo.txt
5.11.1. 删除目录
rm -r prolinux
rm
同样会询问是否删除。输入 y
,按 Enter 键即可删除目录。
不想要提示怎么办?和之前一样,加上 -f
参数:
rm -rf prolinux
5.11.2. 误删文件怎么办?
Linux不像Windows桌面一样有 "回收站"
,使用 rm
删除的文件没有后悔药,无法找回。在这之前,一个良好的习惯尤为重要:
新建名为 trash
的目录,作为自己的文件回收站。将等待删除的文件移动(mv
命令)到这个目录,每隔一段时间删除 trash
目录下的所有文件。
mkdir -p ~/trash
mv prolinux ~/trash
# 每隔一段时间清理回收站
rm -rf ~/trash/*
其实,我在修改重要文件时,也有类似的习惯。我会先复制一份保存做备份,防止误操作。假如改错东西,可以用备份恢复到最初状态。
# 先复制一份做备份
cp prolinux/foo.txt prolinux/foo.txt.bak
# 然后,再修改
nano prolinux/foo.txt
# 如果后悔了,这样恢复
cp prolinux/foo.txt.bak prolinux/foo.txt
5.12. 复制文件
cp
命令:复制目录或文件。
5.12.1. 基础用法
cp 被复制的文件 新的文件名或路径
- 常用参数
-r |
复制目录 |
-v |
显示详细过程 |
--help |
查看帮助信息 |
5.12.2. 操作演示
开始之前
为练习提前创建目录和文件:
cd
mkdir -p ~/prolinux
touch ~/prolinux/foo.txt ~/prolinux/bar.txt
复制文件
复制文件,保持文件名不变:
cp -v ./prolinux/foo.txt /tmp/
复制并修改文件名:
cp -v ./prolinux/foo.txt /tmp/new_foo.txt
如果指定的新文件名或路径已经存在,cp 命令会提示 "cp: overwrite ‘/tmp/foo.txt’?"" ,询问是否覆盖已经有的文件。输入 y ,按 Enter 键就行。
|
在同一个目录下复制一个新文件:
cp -v ./prolinux/bar.txt ./prolinux/new_bar.txt
或
cd ~/prolinux/
cp -v bar.txt new_bar.txt
复制目录
复制当前目录下的 prolinux
文件夹到 /tmp
目录下:
cp -vr prolinux/ /tmp/
查看复制前后的区别:
find ~/prolinux/ /tmp/prolinux/
/root/prolinux/ /root/prolinux/bar.txt /root/prolinux/foo.txt /tmp/prolinux/ /tmp/prolinux/bar.txt /tmp/prolinux/foo.txt
如果复制文件一样,可以指定新的目录
复制后, |
试一试下面这样复制目录:
恭喜你? |
结束之后
删除为练习创建的目录和文件:
cd
rm -rf prolinux /tmp/prolinux*
5.13. 移动(重命名)文件
mv
命令:移动(重命名)文件。
5.13.1. 基础用法
mv
和 cp
的基础用法类似。
mv 被移动的文件 新文件名或路径
- 常用参数
-v |
显示详细过程 |
--help |
查看帮助信息 |
5.13.2. 操作演示
开始之前
为练习提前创建目录和文件:
cd
mkdir -p ~/prolinux
touch ~/prolinux/foo.txt ~/prolinux/bar.txt
移动文件
移动文件,保持文件名不变:
mv -v ./prolinux/foo.txt /tmp/
移动并修改文件名:
mv -v ./prolinux/foo.txt /tmp/new_foo.txt
修改文件名,不改变文件位置:
mv -v ./prolinux/bar.txt ./prolinux/new_bar.txt
或
cd ~/prolinux/
mv -v bar.txt new_bar.txt
移动目录
移动当前目录下的 prolinux
文件夹到 /tmp
目录下:
mv -v prolinux/ /tmp/
查看移动后的情况:
find /tmp/prolinux/
/tmp/prolinux/ /tmp/prolinux/bar.txt /tmp/prolinux/foo.txt
如果移动文件一样,可以指定新的目录
移动后, |
结束之后
删除为练习创建的目录和文件:
cd
rm -rf prolinux /tmp/prolinux*
6. 文件属性
6.1. 简介
6.1.1. 看看我是谁
id
命令可以打印用户和组信息:
id
uid=0(root) gid=0(root) groups=0(root)
当前用户名:root,uid为0
用户所属组:root,gid为0
在当前用户和组的情况下,创建目录和文件后文件属性会显示 "root root"
字样,表示由root用户创建。
当然,id
也可以打印指定用户的信息: id 用户名
。比如,id nobody
。
6.1.2. 一点点准备
创建测试用目录和文件:
mkdir -p ~/prolinux
echo "foo123" > ~/prolinux/foo.txt
echo "bar1234567" > ~/prolinux/bar.txt
chown nobody ~/prolinux/bar.txt
6.1.3. 什么是用户、组和文件权限
查看目录和文件属性:
ls -dl ~/prolinux ~/prolinux/*.txt
drwxr-xr-x 2 root root 4096 Jun 15 14:18 /root/prolinux -rw-r--r-- 1 nobody root 11 Jun 15 14:19 /root/prolinux/bar.txt -rw-r--r-- 1 root root 7 Jun 15 14:19 /root/prolinux/foo.txt
"root root"
和 "nobody root"
表示用户、组设置状态。
"drwxr-xr-x"
和 "-rw-r—r--"
表示文件权限(读、写、执行权限)设置状态。
6.1.4. 文件属性中的用户、组和文件权限是什么关系
- 用户、组设置
-
类似游乐园的门票,属于某种形式的许可或凭证。通过门票类型确定游客类型属于A类还是B类,没有门票(许可)就不能进园区(访问文件)。这个层面,只关心游客类型,不关心游客进去后玩哪种娱乐项目。
用户和组设置作为文件安全的第一道大门,起到甄别用户或程序是否有访问权限的作用。
- 文件权限设置
-
类似进入游乐园后,A类游客只能玩A类包含的娱乐项目(旋转木马、摩天轮),B类游客也只能玩B类包含的娱乐项目(云霄飞车、激流勇进、海盗船)。
A类游客不允许玩儿B类的项目,要玩儿云霄飞车(读或写文件)就得补票,补B类型的门票(重新设置文件权限)。文件权限设置可以让系统知道:用户或程序对文件有读权限、写权限还是执行权限。没有权限,系统会拒绝操作请求。
6.2. 文件用户和组
6.2.1. 每个文件都属于一个用户和一个组
Linux中的每个文件必定属于一个用户和一个组。不管用户还是组都只能一个,不能多个。
查看刚才准备的目录和文件,打印更简洁的文件属性:
ls -dl ~/prolinux/ ~/prolinux/*.txt | awk '{print "用户:"$3" 组:"$4" 名称:"$NF}'
用户: root 组:root 名称:/root/prolinux/ 用户:nobody 组:root 名称:/root/prolinux/bar.txt 用户: root 组:root 名称:/root/prolinux/foo.txt
用户和组不一定要相同,比如
用户:nobody 组:root 名称:/root/prolinux/bar.txt
上面这行表示文件 "/root/prolinux/bar.txt"
属于用户 "nobody"
和 组 "root"
。
再看看 "nobody"
用户的信息:
id nobody
uid=99(nobody) gid=99(nobody) groups=99(nobody)
可以看到用户 "nobody"
和 组 "root"
没有关系。
6.2.2. 修改文件的用户和组设置
chown -v 中的 "-v" 参数仅为打印日志信息,无实际作用,可以忽略。
|
将 "~/prolinux/foo.txt"
用户和组都修改为 "nobody"
:
chown -v nobody:nobody ~/prolinux/foo.txt
changed ownership of ‘/root/prolinux/foo.txt’ from root:root to nobody:nobody
确认设置状态:
ls -l ~/prolinux/foo.txt
-rw-r--r-- 1 nobody nobody 7 Jun 15 14:19 /root/prolinux/foo.txt
看到 "nobody nobody"
说明设置成功。
6.2.3. 修改目录的用户和组设置
chown -v 中的 "-v" 参数仅为打印日志信息,无实际作用,可以忽略。
|
-R
参数表示修改目录以及目录下的所有文件用户和组设置。
修改 "~/prolinux/"
目录的用户和组为 "root"
:
chown -vR root:root ~/prolinux/
ownership of ‘/root/prolinux/bar.txt’ retained as root:root changed ownership of ‘/root/prolinux/foo.txt’ from nobody:nobody to root:root ownership of ‘/root/prolinux/’ retained as root:root
查看目录和目录下的文件属性:
ls -dl ~/prolinux/ ~/prolinux/*.txt
drwxr-xr-x 2 root root 4096 Jun 15 14:18 /root/prolinux/ -rw-r--r-- 1 root root 11 Jun 15 14:19 /root/prolinux/bar.txt -rw-r--r-- 1 root root 7 Jun 15 14:19 /root/prolinux/foo.txt
三行都是 "root root"
,设置成功。
6.2.4. 同时设置多个目录或文件的用户和组
直接在 chown
后加上路径即可,比如
chown -R root:root ~/prolinux/foo.txt ~/prolinux/
chown root:root ~/prolinux/foo.txt ~/prolinux/bar.txt
6.3. 文件权限
6.3.1. 理解文件权限标志
权限分组
每个文件或目录都有三个基于用户的权限组:
- 所有者
-
文件的所有者,具体指某个用户
- 组
-
文件所属的组
- 其它用户
-
所有者和组以外的用户
权限类型
每个文件或目录拥有三个基础权限类型:
- 可读
-
读取文件内容的权限
- 可写
-
写或修改文件的权限
- 可执行
-
查看目录列表(如
ls -l foo/
)或执行脚本(如sh ./foo.sh
)的权限
chmod
Linux系统用 chmod
命令修改文件权限,chmod
有多种表示法(字母法和数字法)指定文件权限。如 chmod +x filename
、chmod 755 filename
。本文仅描述基于八进制的数字法。
数字法有四个八进制数字组成。如 "0755"
,不过会简写成 "755"
。
第一个 "0"
涉及不常用功能,直接忽略之,熟悉后面三个数字即可。
权限符号 | 八进制数字 | 描述 |
---|---|---|
r |
4 |
可读 |
w |
2 |
可写 |
x |
1 |
可执行 |
权限符号组 | 八进制数字 | 描述 |
---|---|---|
rwx |
7 |
可读、可写、可执行 |
rw- |
6 |
可读、可写、可执行 |
r-x |
5 |
可读、可写、可执行 |
r-- |
4 |
可读、可写、可执行 |
-wx |
3 |
可读、可写、可执行 |
-w- |
2 |
可读、可写、可执行 |
--x |
1 |
可读、可写、可执行 |
— |
0 |
可读、可写、可执行 |
看不明白?没关系,看后面……
一点点准备
为详细说明文件权限,提前设置文件的用户和组:
chown -R root:root ~/prolinux/
chown root:nobody ~/prolinux/foo.txt
文件权限说明
不管是系统管理,还是编程写代码,数字法用得最多。字母法和数字法之间的转换属于日常,下文用表格来解释。
- 提前解释下
stat
的参数 -
"%A"
-
第1列,文件权限字母表示法,如
"drwxr-xr-x"
。 "%a"
-
第2列,文件权限数字表示法,如
"755"
。 "%U"
-
第3列,文件所属用户,如
root"
。 "%G"
-
第4列,文件所属组,如
"root"
。 "%n"
-
第5列,目录或文件名称,如
"/root/prolinux/"
。
示例1
列出 ~/prolinux/
目录的文件属性:
ls -dl ~/prolinux/
stat -c '%A %a %U %G %n' ~/prolinux/
drwxr-xr-x 2 root root 4096 Jun 15 14:18 /root/prolinux/ drwxr-xr-x 755 root root /root/prolinux/
用户和组 |
root |
root |
其它用户 |
|||||||
权限分组 |
所有者权限 |
组权限 |
其它用户权限 |
|||||||
文件权限 |
目录 |
可读 |
可写 |
可执行 |
可读 |
可执行 |
可读 |
可执行 |
||
权限模式 |
d |
r |
w |
x |
r |
- |
x |
r |
- |
x |
权限标识 |
4 |
2 |
1 |
4 |
1 |
4 |
1 |
|||
权限模式 |
7 |
5 |
5 |
示例2
列出 ~/prolinux/bar.txt
的文件属性:
ls -l ~/prolinux/bar.txt
stat -c '%A %a %U %G %n' ~/prolinux/bar.txt
-rw-r--r-- 1 root root 11 Jun 16 10:41 /root/prolinux/bar.txt -rw-r--r-- 644 root root /root/prolinux/bar.txt
用户和组 |
root |
root |
其它用户 |
|||||||
权限分组 |
所有者权限 |
组权限 |
其它用户权限 |
|||||||
文件权限 |
文件 |
可读 |
可写 |
可读 |
可读 |
|||||
权限模式 |
- |
r |
w |
- |
r |
- |
- |
r |
- |
- |
权限标识 |
4 |
2 |
4 |
4 |
||||||
权限模式 |
6 |
4 |
4 |
示例3
列出 ~/prolinux/foo.txt
的文件属性:
ls -l ~/prolinux/foo.txt
stat -c '%A %a %U %G %n' ~/prolinux/foo.txt
-rw-r--r-- 1 root nobody 7 Jun 16 10:41 /root/prolinux/foo.txt -rw-r--r-- 644 root nobody /root/prolinux/foo.txt
用户和组 |
root |
nobody |
其它用户 |
|||||||
权限分组 |
所有者权限 |
组权限 |
其它用户权限 |
|||||||
文件权限 |
可读 |
可写 |
可读 |
可读 |
||||||
权限模式 |
- |
r |
w |
- |
r |
- |
- |
r |
- |
- |
权限标识 |
文件 |
4 |
2 |
4 |
4 |
|||||
权限模式 |
6 |
4 |
4 |
6.3.2. 修改文件权限
chmod -v 中的 "-v" 参数仅为打印日志信息,无实际作用,可以忽略。
|
chmod -v 755 ~/prolinux/foo.txt
mode of ‘/root/prolinux/foo.txt’ changed from 0644 (rw-r--r--) to 0755 (rwxr-xr-x)
6.3.3. 修改目录权限
chmod -v 中的 "-v" 参数仅为打印日志信息,无实际作用,可以忽略。
|
-R
参数表示修改目录以及目录下的所有文件权限设置。
chmod -vR 755 ~/prolinux/
mode of ‘/root/prolinux/’ retained as 0755 (rwxr-xr-x) mode of ‘/root/prolinux/bar.txt’ changed from 0644 (rw-r--r--) to 0755 (rwxr-xr-x) mode of ‘/root/prolinux/foo.txt’ retained as 0755 (rwxr-xr-x)
6.3.4. 同时设置多个目录和文件的权限
chmod -R 755 ~/prolinux/foo.txt ~/prolinux/
chmod 644 ~/prolinux/foo.txt ~/prolinux/bar.txt
7. 输入输出重定向
输入输出重定向,常偷懒称作IO重定向。
IO是Input/Output的简写。 |
7.1. 什么是IO重定向
“用 键盘 打字,屏幕 能实时看到输入的文字。”
-
键盘是一种输入(input)设备,Linux中称作 标准输入(stdin)设备;
-
屏幕是一种输出(output)设备,Linux中称作 标准输出(stdout)设备。
“打错字时,屏幕上能看到醒目的软件错误提示。比如, 发现未知单词 Lxinu。”
-
屏幕是一种错误输出(output)设备,Linux中称作 标准错误输出,或 错误输出(stderr)设备。
IO重定向是Linux系统中常用的功能,可以在执行命令时改变标准输入/输出设备。
打印内容到屏幕的例子:
echo prolinux
加入重定向后的例子:
echo prolinux > ~/foo.txt
上面的例子,将本该显示到屏幕的执行结果保存到文件 "foo.txt"
。通过重定向功能将输出设备从屏幕改成了文件。
7.2. 标准输出重定向(stdout)
">"
或"1>"
符号-
覆盖写入,文件内容先被清空,然后写入新内容。
">>"
或"1>>"
符号-
追加写入,新内容追加到文件末尾,不影响已有内容。
7.2.1. 什么是标准输出重定向
标准输出重定向把命令的执行结果(内容)写入文件,而不是显示在屏幕上。
除了文件,标准输出重定向还可以 “写入” 其它地方。这些不在本文讨论范围。 |
7.2.2. 标准输出重定向能做什么
覆盖写入
在终端执行某些命令时,通常会在屏幕上看到执行结果。比如:
[root@prolinux ~]# ls /usr/lib
binfmt.d grub modprobe.d rpm systemd
debug kbd modules sendmail tmpfiles.d
dracut kdump modules-load.d sendmail.postfix tuned
firmware kernel polkit-1 sse2 udev
games locale python2.7 sysctl.d yum-plugins
ls /usr/lib
的执行结果较少,显示没问题。
在系统日志中查找服务启动日志,这样的情况就有问题了。
试一试:
journalctl | grep Starting
8月 16 16:10:14 localhost.localdomain kernel: SELinux: Starting in permissive mode
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting Swap.
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting -.slice.
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting udev Control Socket.
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting System Slice.
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting Slices.
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting udev Kernel Socket.
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting Local File Systems.
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting Timers.
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting Journal Socket.
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting Create list of required static device nodes for the current kernel...
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting Sockets.
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting dracut cmdline hook...
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting Setup Virtual Console...
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting Apply Kernel Variables...
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting Journal Service...
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting Create Static Device Nodes in /dev...
...
...
...
内容太多,屏幕可能显示不完。
再试一试:
journalctl | grep Starting > ~/out.log
"> ~/out.log" 可以用 "1> ~/out.log" 代替。
|
“乱码”去哪儿了?
之前在屏幕上显示的内容,写到了 "~/out.log"
文件。如下:
[root@prolinux ~]# cat ~/out.log
8月 16 16:10:14 localhost.localdomain kernel: SELinux: Starting in permissive mode
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting Swap.
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting -.slice.
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting udev Control Socket.
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting System Slice.
8月 16 16:10:14 localhost.localdomain systemd[1]: Starting Slices.
...
...
...
追加写入
一个简单的例子:
echo line1 > ~/foo.txt
echo line2 >> ~/foo.txt
echo line3 >> ~/foo.txt
看看文件内容:
[root@prolinux ~]# cat ~/foo.txt
line1
line2
line3
可以看到,新内容始终在结尾处追加写入。
看看覆盖写入会发生什么:
echo line4 > ~/foo.txt
当前的文件内容:
[root@prolinux ~]# cat ~/foo.txt
line4
7.3. 标准输入重定向(stdin)
"<"
或"0<"
符号-
将文件内容作为命令输入。
"<<"
符号(Here Document)-
一种特殊目的的输入重定向,在交互式程序或命令中实现
"块"
输入。
7.3.1. 什么是标准输入重定向
执行命令时,用标准输入重定向能从文件内容或其它命令结果读取参数。
标准输入重定向常用于需要大量输入或某些交互式场景。
这样,我们不用手动输入参数,也可以运行命令。
7.3.2. 标准输入重定向能做什么
示例1:wc命令
下面两个示例分别演示如何用 wc
命令统计 "foo.txt"
的行数。
准备测试文件:
echo line1 > ~/foo.txt
echo line2 >> ~/foo.txt
echo line3 >> ~/foo.txt
统计行数:
wc -l ~/foo.txt
3 /root/foo.txt
使用标准输入重定向统计行数:
wc -l < ~/foo.txt
3
两个命令得到相同的文件行数:3。
命令1指定了参数:"~/foo.txt"
,所以结果中包含文件名。
命令2则没有指定文件名,而是通过标准输入重定向读取文件内容后,将文件内容传递给 wc
命令。
一个命令指定文件名,一个命令直接传递文件内容。
示例2:wc命令(Here Document)
Here Document
可以实现在没有 "foo.txt"
文件的情况下,统计出行数。
wc -l << EOF
line1
line2
line3
EOF
3
命令3同样得到文件行数:3。
命令3中有两个重点:
-
"<<"
,Here Document符号,表示标准输入重定向; -
"EOF"
,内容起止符号(成对出现),表示内容块开始和终止。
终止EOF符号前不能有空格。 |
7.3.3. 延伸
命令1/2/3执行结果相同,但实用程度排名则是这样:
正常 << 便捷 << 超级实用
对标准输入重定向理解到位,可是能极大提升Linux使用效率。
场景:导入/导出MySQL数据
Linux作为开发环境、服务器系统首选,搭配MySQL使用是很自然的事情。导入/导出MySQL数据基本成为了日常操作。
事实上,99%的人都是在用GUI图形工具处理导入导出。实际上,更简单的操作应该是这样:
mysqldump -u用户名 -p密码 数据库名称 > backup_数据库名称_2021xxxx.sql
mysql -u用户名 -p密码 数据库名称 < backup_数据库名称_2021xxxx.sql
场景:非交互式创建文件
cat << EOF > ~/foo.txt
line1
line2
line3
EOF
在脚本、技术文档或文章中用 "<< EOF"
这样的组合实在是非常舒服的一件事情。
7.4. 错误输出重定向(stderr)
错误输出重定向和标准输出重定向都是把命令的执行结果(内容)写入文件,而不是显示在屏幕上。
不同的地方在于,错误输出重定向仅在命令执行失败时有效。具体的,可以看后面的例子。
除了文件,错误输出重定向还可以 “写入” 其它地方。这些不在本文讨论范围。 |
在命令行中单个 "2>"
和两个 "2>>"
的用法和标准输出重定向相同。
注意是数字 2 不是 1 。
|
极少数情况下会用到 2>&1 。"2>&1" 表示将错误输出(stderr)重定向到标准输出(stdout)。
|
7.4.1. 例子
例子1
故意查看不存在的文件:
ls -l /usr/include ~/abcdefghijk /test/foo.txt
[root@prolinux ~]# ls -l /usr/include ~/abcdefghijk /test/foo.txt
ls: 无法访问/root/abcdefghijk: 没有那个文件或目录
ls: 无法访问/test/foo.txt: 没有那个文件或目录
/usr/include:
总用量 0
drwxr-xr-x. 2 root root 26 8月 27 2019 python2.7
可以看到 "/usr/include"
的文件,另外两个文件则报错。
例子2
用错误输出重定向改造下,错误提示写到文件中:
ls -l /usr/include ~/abcdefghijk /test/foo.txt 2>~/error.log
[root@prolinux ~]# ls -l /usr/include ~/abcdefghijk /test/foo.txt 2>~/error.log
/usr/include:
总用量 0
drwxr-xr-x. 2 root root 26 8月 27 2019 python2.7
这次屏幕看起来干净些,错误提示也“消失了”。
看看 "~/error.log"
的内容:
[root@prolinux ~]# cat ~/error.log ls: 无法访问/root/abcdefghijk: 没有那个文件或目录 ls: 无法访问/test/foo.txt: 没有那个文件或目录
8. 管道
8.1. 管道
管道("|"
)可以将两个命令连接起来,上个命令的标准输出(stdout)作为下个命令的标准输入(stdin)。
结合管道可以完成更加复杂的命令操作。
8.1.1. 基础用法
命令1 | 命令2 | 命令3 | ... | 命令N
管道前后的空格只是为了好看。 |
8.1.2. 示例
列出 "/usr"
目录下的前5个文件或目录
ls -l /usr | head -n 5
total 124 dr-xr-xr-x. 2 root root 36864 Feb 4 14:08 bin drwxr-xr-x. 2 root root 4096 Apr 11 2018 etc drwxr-xr-x. 2 root root 4096 Apr 11 2018 games drwxr-xr-x. 46 root root 4096 Jul 11 2020 include
打印运行进程的用户名
ps aux | tail -n +2 | cut -d ' ' -f 1 | sort -u
chrony dbus mysql nginx nobody polkitd root tcpdump
- 参数说明
-
- 排除标题行
-
tail -n +2
可以过滤ps aux
输出的第一行(标题行),最后只打印第二行到最后一行 - 分列
-
cut -d ' ' -f 1
表示用空格分隔行,打印第一列 - 排序去重
-
sort -u
这个示例比前面的更加复杂,也充分展示了管道的强大之处。
完成这样的小case不用脚本,不用编程,简直十分跟手。
另外,不需要担心这些没见过的“陌生人”,下一章会详细介绍这些命令的使用方法和参数。
8.1.3. 延伸
极少数命令会打印内容到错误输出(stderr),管道会失效。
“怎么办呢?”
“没关系,输出重定向就行了~”
就像这样:
strace -f -p 1038 2>&1 | grep NULL
[pid 7888] futex(0x1ebe544, FUTEX_WAIT_PRIVATE, 8288, NULL <unfinished ...> [pid 889] futex(0x1ebe544, FUTEX_WAIT_PRIVATE, 8288, NULL <unfinished ...> [pid 888] futex(0x1ebe544, FUTEX_WAIT_PRIVATE, 8288, NULL <unfinished ...> [pid 25199] futex(0x1ebe544, FUTEX_WAIT_PRIVATE, 8288, NULL <unfinished ...> [pid 25198] futex(0x1ebe544, FUTEX_WAIT_PRIVATE, 8288, NULL <unfinished ...> [pid 1671] futex(0x1ebe544, FUTEX_WAIT_PRIVATE, 8288, NULL <unfinished ...> [pid 1344] futex(0x1e8b044, FUTEX_WAIT_PRIVATE, 1, NULL <unfinished ...> [pid 1343] rt_sigtimedwait([HUP QUIT TERM], NULL, NULL, 8 <unfinished ...> [pid 1314] futex(0x33bb424, FUTEX_WAIT_PRIVATE, 1, NULL <unfinished ...> [pid 1311] futex(0x33bb304, FUTEX_WAIT_PRIVATE, 1, NULL <unfinished ...> [pid 1308] futex(0x33bb154, FUTEX_WAIT_PRIVATE, 1, NULL <unfinished ...> [pid 1307] futex(0x33bb0c4, FUTEX_WAIT_PRIVATE, 1, NULL <unfinished ...> [pid 1306] futex(0x33bb034, FUTEX_WAIT_PRIVATE, 1, NULL <unfinished ...> [pid 1305] futex(0x33bafa4, FUTEX_WAIT_PRIVATE, 3, NULL <unfinished ...>
"2>&1"
表示将错误输出(stderr)重定向到标准输出(stdout)。
系统默认未安装 strace 命令,需要提前安装:yum install -y strace
|
9. 常用命令
9.1. 我在哪儿(pwd)
pwd
- 查看当前(工作)目录绝对路径
9.1.1. 基础用法
pwd
无常用参数。
9.1.2. 操作演示
查看当前路径
cd /usr
pwd
cd /usr/share/zoneinfo/Asia
pwd
cd
pwd
/usr /usr/share/zoneinfo/Asia /root
9.2. 排序和去重(sort)
sort
- 将管道、标准输入或文件的行排序后,打印到标准输出
9.2.1. 基础用法
sort 文件名或路径
命令 | sort
- 常用参数
-u |
排序后,去重 |
--help |
帮助信息 |
9.2.2. 操作演示
开始之前
cat << EOF > ~/foo.txt
8888
5555
5555
8888
6666
ZZZZ
1111
aaaa
3333
0000
2222
ZZZZ
1111
aaaa
3333
0000
2222
EOF
cat << EOF > ~/ip.txt
8.8.8.8
8.8.8.8
125.64.74.81
125.93.75.146
58.47.128.241
4.4.4.4
4.4.4.4
58.47.128.241
124.94.202.242
124.225.123.2
60.16.181.208
116.255.130.10
117.81.43.159
61.146.41.106
113.6.18.36
123.6.150.215
123.188.196.36
116.52.35.6
121.228.43.0
122.224.236.26
EOF
排序
方法一:从文件读取行:
sort ~/foo.txt
方法二:从管道读取行:
cat ~/foo.txt | sort
方法三:从标准输入读取行(非主流的方法):
sort << EOF
8888
5555
5555
8888
6666
ZZZZ
1111
aaaa
3333
0000
2222
ZZZZ
1111
aaaa
3333
0000
2222
EOF
以上方法都会得到相同的结果:
0000 0000 1111 1111 2222 2222 3333 3333 5555 5555 6666 8888 8888 aaaa aaaa ZZZZ ZZZZ
排序去重
"-u"
参数是关键。试一试:
sort -u ~/foo.txt
0000 1111 2222 3333 5555 6666 8888 aaaa ZZZZ
现在,执行结果中的重复行已经被过滤掉。
可以试一试看 cat ~/foo.txt | sort -u
又是什么样。
延伸:排序IPv4地址
sort -u -t . -k 1n,1n -k 2n,2n -k 3n,3n -k 4n,4n ~/ip.txt
偷懒的方法:
sort -u -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n ~/ip.txt
- 参数说明
-u |
排序后,去重 |
-t |
指定分隔符,用 |
-k |
排序关键字,参数值格式: |
更加偷懒的方法:
sort -u -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4 ~/ip.txt
- 参数说明
-u |
同上 |
-t |
同上 |
-n |
以数字规则排序 |
-k |
同上,用 |
以上方法都会得到相同的结果:
4.4.4.4 8.8.8.8 58.47.128.241 60.16.181.208 61.146.41.106 113.6.18.36 116.52.35.6 116.255.130.10 117.81.43.159 121.228.43.0 122.224.236.26 123.6.150.215 123.188.196.36 124.94.202.242 124.225.123.2 125.64.74.81 125.93.75.146
“学废了没?” “试试IPv6地址排序?” “安排~” |
结束之后
删除临时文件:
rm -f ~/foo.txt ~/ip.txt
9.3. 快捷方式(ln)
ln
- 创建目录或文件的快捷方式,也可以称做软链接
ln 用法较多,本文仅讨论软链接。
|
9.3.1. 为什么要用软链接
-
文件太大,不想移动文件;
-
文件不能随便修改位置,可能导致软件运行出错;
-
想加一个方便的入口;
-
……
9.3.2. 基础用法
ln -s 源路径 目标路径
- 常用参数
-s |
创建软链接 |
--help |
帮助信息 |
9.3.3. 操作演示
开始之前
准备测试文件和目录:
mkdir -p /tmp/foo
echo 'Hello World!' > /tmp/foo/source.txt
看看文件:
ls -l /tmp/foo/source.txt
cat /tmp/foo/source.txt
total 4 -rw-r--r-- 1 root root 13 Feb 19 22:27 /tmp/foo/source.txt Hello World!
创建文件的快捷方式
创建 "source.txt"
的快捷方式:
ln -s /tmp/foo/source.txt ~/target.txt
看看 target.txt
的文件属性:
ls -l ~/target.txt
lrwxrwxrwx 1 root root 14 Feb 19 22:30 /root/target.txt -> /tmp/foo/source.txt
箭头符号 "→"
是软链接最重要的标志。
那文件内容呢?再看:
cat ~/target.txt
Hello World!
我家小朋友都看出来了,你呢?
"~/target.txt"
是 "/tmp/foo/source.txt"
的软链接。
- 最后强调下
-
-
删除
"~/target.txt"
后,"/tmp/foo/source.txt"
还在 -
删除
"/tmp/foo/source.txt"
后,"~/target.txt"
可就不能用了哦
-
创建目录的快捷方式
创建 "/tmp/foo"
的快捷方式:
ln -s /tmp/foo /tmp/foo.link
看看:
ls -l /tmp/foo.link
lrwxrwxrwx 1 root root 8 Feb 19 22:48 /tmp/foo.link -> /tmp/foo
悄悄加个 "/"
在最后,再看看:
ls -l /tmp/foo.link/
total 4 -rw-r--r-- 1 root root 13 Feb 19 22:27 source.txt
加不加,可是不一样的哦。
结束之后
删除临时文件:
rm -rf /tmp/foo
rm
也能删除软链接:
rm -f /tmp/foo.link ~/target.txt
9.4. 下载工具(curl)
curl
- 一个用来传输数据的命令行工具(就是个功能丰富的下载工具)
curl 支持非常多的网络协议,本文仅介绍HTTP协议。
|
9.4.1. 基础用法
URL一定要用一对单引号包住,否则URL中的特殊符合会导致错误。 |
curl -I url
curl -v -I url
curl url -o 文件名
curl -H -X HTTP方法 url
curl -A "User-Agent" url
- 常用参数
-I |
仅显示HTTP头信息 |
-v |
显示更多HTTP信息,常用于诊断问题 |
-o |
下载,另存为 |
-X |
指定HTTP方法,HTTP协议的GET/POST/PUT/OPTIONS/DELETE/HEAD等等 |
-H |
自定义HTTP头 |
-A |
指定浏览器标识(User-Agent) |
--help all |
帮助信息 |
9.4.2. 操作演示
下载文件并保存
下载文件到当前路径,文件名为 "centos-logo-white.png"
:
curl 'https://www.centos.org/assets/img/centos-logo-white.png' -o centos-logo-white.png
指定文件路径:
curl 'https://www.centos.org/assets/img/centos-logo-white.png' -o /tmp/123.png
查看下载的文件:
file /tmp/123.png centos-logo-white.png
/tmp/123.png: PNG image data, 331 x 93, 8-bit/color RGBA, non-interlaced centos-logo-white.png: PNG image data, 331 x 93, 8-bit/color RGBA, non-interlaced
用 file
看到,从官网下载的CentOS LOGO图片分辨率为 "331 x 93"
。
查看HTTP头信息
绝对的装X神技,开发者必备的常用技能。
一秒诊断网站故障:
curl -I 'https://www.centos.org/assets/img/centos-logo-white.png'
HTTP/1.1 200 OK Date: Thu, 04 Mar 2021 12:45:45 GMT Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips Strict-Transport-Security: max-age=31536000 X-Frame-Options: SAMEORIGIN X-Xss-Protection: 1; mode=block X-Content-Type-Options: nosniff Referrer-Policy: same-origin Last-Modified: Thu, 04 Mar 2021 12:25:14 GMT ETag: "1d8f-5bcb50f3dd2d8" Accept-Ranges: bytes Content-Length: 7567 Content-Type: image/png
看到 "HTTP/1.1 200 OK"
表示网站能够访问。出现403/404/502情况,说明网站无法访问。
更多HTTP协议细节,请移步 MDN Web Docs |
查看更多HTTP头信息
显示更多访问细节:
curl -vI 'https://www.centos.org/assets/img/centos-logo-white.png'
或
curl -v -I 'https://www.centos.org/assets/img/centos-logo-white.png'
* About to connect() to www.centos.org port 443 (#0) * Trying 81.171.33.202... * Connected to www.centos.org (81.171.33.202) port 443 (#0) * Initializing NSS with certpath: sql:/etc/pki/nssdb * CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none * SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 * Server certificate: * subject: CN=centos.org * start date: Jan 04 06:50:09 2021 GMT * expire date: Apr 04 06:50:09 2021 GMT * common name: centos.org * issuer: CN=R3,O=Let's Encrypt,C=US > HEAD / HTTP/1.1 > User-Agent: curl/7.29.0 > Host: www.centos.org > Accept: */* > < HTTP/1.1 200 OK HTTP/1.1 200 OK ...... ......
指定浏览器标识(User-Agent)
模拟百度访问CentOS官网:
curl -vI 'https://www.centos.org/' -A 'Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)'
* About to connect() to www.centos.org port 443 (#0) * Trying 81.171.33.202... * Connected to www.centos.org (81.171.33.202) port 443 (#0) * Initializing NSS with certpath: sql:/etc/pki/nssdb * CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none * SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 * Server certificate: * subject: CN=centos.org * start date: Jan 04 06:50:09 2021 GMT * expire date: Apr 04 06:50:09 2021 GMT * common name: centos.org * issuer: CN=R3,O=Let's Encrypt,C=US > HEAD / HTTP/1.1 > User-Agent: Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html) > Host: www.centos.org > Accept: */* > < HTTP/1.1 200 OK HTTP/1.1 200 OK ...... ......
注意屏幕中的 "User-Agent"
一行。
去掉HTTP头信息:
curl 'https://www.centos.org/' -A 'Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)' -o /dev/null
Linux最有意思的地方就是:你永远不知道还有多少黑科技! "/dev/null" 表示将内容写到黑洞,丢东西进去什么事情都不会发生。
|
9.4.3. 延伸
自定义HTTP头和指定HTTP方法
运行本示例需要可用的网站URL。"http://localhost:9200" 仅做示意,是无法访问的。
|
默认 curl
使用GET方法请求网站,也可以用 "-X"
指定其它的HTTP方法。
curl -H "Content-Type: application/json" -X POST 'http://localhost:9200/wecompany/employee/2?pretty' -d '
{
"first_name" : "Jane",
"last_name" : "Smith",
"age" : 32,
"about" : "I like to collect rock albums",
"interests": [ "music" ]
}
'
"-H "Content-Type: application/json""
-
设置HTTP头:Content-Type,表示本次用JSON格式传输请求参数
"-X POST"
-
指定HTTP方法,向网站服务器发起POST请求
"-d …"
-
POST请求的JSON格式参数
9.5. 下载工具(wget)
wget
- 功能强大的下载工具,相比 curl
来说功能更加侧重下载。
wget 功能丰富,本文仅介绍基础功能。
|
9.5.1. 基础用法
URL一定要用一对单引号包住,否则URL中的特殊符合会导致错误。 |
wget -c url
wget url -O 文件保存位置
wget -c url -O 文件保存位置
- 常用参数
-c |
断点续传下载文件 |
-O |
指定下载文件保存位置,如果文件已经存在则覆盖 |
-h |
帮助信息 |
9.5.2. 操作演示
断点续传下载文件
下载一个934M的安装镜像文件:
wget http://mirrors.163.com/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso
--2021-03-29 13:10:43-- http://mirrors.163.com/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso
Resolving mirrors.163.com (mirrors.163.com)... 42.186.18.104, 42.186.18.105
Connecting to mirrors.163.com (mirrors.163.com)|42.186.18.104|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1020264448 (973M) [application/octet-stream]
Saving to: ‘CentOS-7-x86_64-Minimal-2009.iso’
5% [====> ] 51,857,416 13.7MB/s eta 60s
下载到约 "1%"
时,按 Ctrl+C 故意停止下载。
查看下载的ISO文件:
ll CentOS-7-x86_64-Minimal-2009.iso*
-rw-r--r-- 1 root root 52018640 Mar 29 13:10 CentOS-7-x86_64-Minimal-2009.iso
看到 "52018640"
大概已经下载了50M,明显没有下载完。
再执行一次命令,接着下载:
wget http://mirrors.163.com/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso
--2021-03-29 13:14:49-- http://mirrors.163.com/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso
Resolving mirrors.163.com (mirrors.163.com)... 42.186.18.105, 42.186.18.104
Connecting to mirrors.163.com (mirrors.163.com)|42.186.18.105|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1020264448 (973M) [application/octet-stream]
Saving to: ‘CentOS-7-x86_64-Minimal-2009.iso.1’
4% [====> ] 44,391,528 16.0MB/s
查看这次下载的ISO文件:
ll CentOS-7-x86_64-Minimal-2009.iso*
-rw-r--r-- 1 root root 52018640 Mar 29 13:10 CentOS-7-x86_64-Minimal-2009.iso
-rw-r--r-- 1 root root 46634976 Mar 29 13:14 CentOS-7-x86_64-Minimal-2009.iso.1
多了一个 "CentOS-7-x86_64-Minimal-2009.iso.1"
?
执行了两次 wget
得到两个单独的ISO文件,这不是我们想要的。
“我想断点续传……”
加上 "-c"
表示断点续传:
wget -c http://mirrors.163.com/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso
--2021-03-29 13:18:22-- http://mirrors.163.com/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso
Resolving mirrors.163.com (mirrors.163.com)... 42.186.18.105, 42.186.18.104
Connecting to mirrors.163.com (mirrors.163.com)|42.186.18.105|:80... connected.
HTTP request sent, awaiting response... 206 Partial Content
Length: 1020264448 (973M), 968245808 (923M) remaining [application/octet-stream]
Saving to: ‘CentOS-7-x86_64-Minimal-2009.iso’
12% [+++++========> ] 123,450,640 11.7MB/s eta 60s
你可以用 ll
命令看看效果:
ll CentOS-7-x86_64-Minimal-2009.iso*
指定下载文件保存位置,如果文件已经存在则覆盖
下载文件名和保存文件名("CentOS-7-x86_64-Minimal-2009.torrent"
)相同:
wget http://mirrors.163.com/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-2009.torrent -O /tmp/CentOS-7-x86_64-Minimal-2009.torrent
保存为不同的文件名("CentOS7_Minimal.torrent"
):
wget http://mirrors.163.com/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-2009.torrent -O /tmp/CentOS7_Minimal.torrent
指定下载文件保存位置,如果文件已经存在则断点续传
断点续传方式下载文件 "CentOS-7-x86_64-Minimal-2009.iso "
,保存到目录 "/tmp"
:
wget -c http://mirrors.163.com/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso -O /tmp/CentOS-7-x86_64-Minimal-2009.iso
--2021-03-29 13:38:56-- http://mirrors.163.com/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso
Resolving mirrors.163.com (mirrors.163.com)... 42.186.18.105, 42.186.18.104
Connecting to mirrors.163.com (mirrors.163.com)|42.186.18.105|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1020264448 (973M) [application/octet-stream]
Saving to: ‘/tmp/CentOS-7-x86_64-Minimal-2009.iso’
14% [================> ] 149,493,656 11.7MB/s eta 65s
--2021-03-29 13:43:15-- http://mirrors.163.com/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso
Resolving mirrors.163.com (mirrors.163.com)... 42.186.18.105, 42.186.18.104
Connecting to mirrors.163.com (mirrors.163.com)|42.186.18.105|:80... connected.
HTTP request sent, awaiting response... 206 Partial Content
Length: 1020264448 (973M), 942778880 (899M) remaining [application/octet-stream]
Saving to: ‘/tmp/CentOS-7-x86_64-Minimal-2009.iso’
100%[++++++++======================================================>] 1,020,264,448 11.7MB/s in 76s
2021-03-29 13:44:31 (11.8 MB/s) - ‘/tmp/CentOS-7-x86_64-Minimal-2009.iso’ saved [1020264448/1020264448]
结束之后
删除临时文件:
rm -f /tmp/CentOS-7-x86_64-Minimal-2009.iso* CentOS-7-x86_64-Minimal-2009.iso* /tmp/CentOS-7-x86_64-Minimal-2009.torrent /tmp/CentOS7_Minimal.torrent
9.6. 打印前N行(head)
head
- 打印文件的前N行到标准输出
9.6.1. 基础用法
head -n 数量 文件名或路径
命令 | head -n 数量
- 常用参数
-n |
打印前N行。以 '-' 开头时,打印除最后N行以外的所有行。 |
--help |
帮助信息 |
9.6.2. 操作演示
开始之前
准备演示用的文件:
ls -l / | cat -n > ~/foo.txt
1 total 64 2 lrwxrwxrwx. 1 root root 7 Feb 15 2019 bin -> usr/bin 3 dr-xr-xr-x. 5 root root 4096 Aug 9 2019 boot 4 drwxr-xr-x 5 root root 4096 Aug 1 2019 data 5 drwxr-xr-x 19 root root 2980 Apr 21 2020 dev 6 drwxr-xr-x. 91 root root 4096 Jul 11 2020 etc 7 drwxr-xr-x. 3 root root 4096 Jun 27 2019 home 8 lrwxrwxrwx. 1 root root 7 Feb 15 2019 lib -> usr/lib 9 lrwxrwxrwx. 1 root root 9 Feb 15 2019 lib64 -> usr/lib64 10 drwx------. 2 root root 16384 Feb 15 2019 lost+found 11 drwxr-xr-x. 2 root root 4096 Apr 11 2018 media 12 drwxr-xr-x. 2 root root 4096 Apr 11 2018 mnt 13 drwxr-xr-x. 4 root root 4096 May 13 2019 opt 14 dr-xr-xr-x 88 root root 0 Apr 12 2020 proc 15 dr-xr-x---. 9 root root 4096 Feb 19 12:40 root 16 drwxr-xr-x 25 root root 740 Feb 4 14:08 run 17 lrwxrwxrwx. 1 root root 8 Feb 15 2019 sbin -> usr/sbin 18 drwxr-xr-x. 2 root root 4096 Apr 11 2018 srv 19 dr-xr-xr-x 13 root root 0 Feb 18 10:24 sys 20 drwxrwxrwt. 8 root root 4096 Feb 19 03:11 tmp 21 drwxr-xr-x. 13 root root 4096 Feb 15 2019 usr 22 drwxr-xr-x. 20 root root 4096 May 27 2019 var
打印前14行
head -n 14 ~foo.txt
1 total 64 2 lrwxrwxrwx. 1 root root 7 Feb 15 2019 bin -> usr/bin 3 dr-xr-xr-x. 5 root root 4096 Aug 9 2019 boot 4 drwxr-xr-x 5 root root 4096 Aug 1 2019 data 5 drwxr-xr-x 19 root root 2980 Apr 21 2020 dev 6 drwxr-xr-x. 91 root root 4096 Jul 11 2020 etc 7 drwxr-xr-x. 3 root root 4096 Jun 27 2019 home 8 lrwxrwxrwx. 1 root root 7 Feb 15 2019 lib -> usr/lib 9 lrwxrwxrwx. 1 root root 9 Feb 15 2019 lib64 -> usr/lib64 10 drwx------. 2 root root 16384 Feb 15 2019 lost+found 11 drwxr-xr-x. 2 root root 4096 Apr 11 2018 media 12 drwxr-xr-x. 2 root root 4096 Apr 11 2018 mnt 13 drwxr-xr-x. 4 root root 4096 May 13 2019 opt 14 dr-xr-xr-x 88 root root 0 Apr 12 2020 proc
打印最后8行以外的所有行
head -n -8 ~/foo.txt
1 total 64 2 lrwxrwxrwx. 1 root root 7 Feb 15 2019 bin -> usr/bin 3 dr-xr-xr-x. 5 root root 4096 Aug 9 2019 boot 4 drwxr-xr-x 5 root root 4096 Aug 1 2019 data 5 drwxr-xr-x 19 root root 2980 Apr 21 2020 dev 6 drwxr-xr-x. 91 root root 4096 Jul 11 2020 etc 7 drwxr-xr-x. 3 root root 4096 Jun 27 2019 home 8 lrwxrwxrwx. 1 root root 7 Feb 15 2019 lib -> usr/lib 9 lrwxrwxrwx. 1 root root 9 Feb 15 2019 lib64 -> usr/lib64 10 drwx------. 2 root root 16384 Feb 15 2019 lost+found 11 drwxr-xr-x. 2 root root 4096 Apr 11 2018 media 12 drwxr-xr-x. 2 root root 4096 Apr 11 2018 mnt 13 drwxr-xr-x. 4 root root 4096 May 13 2019 opt 14 dr-xr-xr-x 88 root root 0 Apr 12 2020 proc
foo.txt共22行,"-n 14" 和 "-n -8" 得到的结果相同。
|
打印来自标准输出的前3行
cat ~/foo.txt | head -n 3
1 total 64 2 lrwxrwxrwx. 1 root root 7 Feb 15 2019 bin -> usr/bin 3 dr-xr-xr-x. 5 root root 4096 Aug 9 2019 boot
结束之后
删除临时文件:
rm -f ~/foo.txt
9.7. 打印后N行(tail)
tail
- 打印文件的后N行到标准输出
9.7.1. 基础用法
tail -n 数量 文件名或路径
命令 | tail -n 数量
tail -f 文件名或路径
- 常用参数
-f |
实时滚动刷新,打印新增的数据 |
-n |
打印最后N行。以 '+' 开头时,从第N行开始打印所有行 |
--help |
帮助信息 |
9.7.2. 操作演示
开始之前
准备演示用的文件:
ls -l / | cat -n > ~/foo.txt
touch ~/bar.txt
1 total 64 2 lrwxrwxrwx. 1 root root 7 Feb 15 2019 bin -> usr/bin 3 dr-xr-xr-x. 5 root root 4096 Aug 9 2019 boot 4 drwxr-xr-x 5 root root 4096 Aug 1 2019 data 5 drwxr-xr-x 19 root root 2980 Apr 21 2020 dev 6 drwxr-xr-x. 91 root root 4096 Jul 11 2020 etc 7 drwxr-xr-x. 3 root root 4096 Jun 27 2019 home 8 lrwxrwxrwx. 1 root root 7 Feb 15 2019 lib -> usr/lib 9 lrwxrwxrwx. 1 root root 9 Feb 15 2019 lib64 -> usr/lib64 10 drwx------. 2 root root 16384 Feb 15 2019 lost+found 11 drwxr-xr-x. 2 root root 4096 Apr 11 2018 media 12 drwxr-xr-x. 2 root root 4096 Apr 11 2018 mnt 13 drwxr-xr-x. 4 root root 4096 May 13 2019 opt 14 dr-xr-xr-x 88 root root 0 Apr 12 2020 proc 15 dr-xr-x---. 9 root root 4096 Feb 19 12:40 root 16 drwxr-xr-x 25 root root 740 Feb 4 14:08 run 17 lrwxrwxrwx. 1 root root 8 Feb 15 2019 sbin -> usr/sbin 18 drwxr-xr-x. 2 root root 4096 Apr 11 2018 srv 19 dr-xr-xr-x 13 root root 0 Feb 18 10:24 sys 20 drwxrwxrwt. 8 root root 4096 Feb 19 03:11 tmp 21 drwxr-xr-x. 13 root root 4096 Feb 15 2019 usr 22 drwxr-xr-x. 20 root root 4096 May 27 2019 var
打印最后10行
tail -n 10 ~/foo.txt
13 drwxr-xr-x. 4 root root 4096 May 13 2019 opt 14 dr-xr-xr-x 88 root root 0 Apr 12 2020 proc 15 dr-xr-x---. 9 root root 4096 Feb 19 12:40 root 16 drwxr-xr-x 25 root root 740 Feb 4 14:08 run 17 lrwxrwxrwx. 1 root root 8 Feb 15 2019 sbin -> usr/sbin 18 drwxr-xr-x. 2 root root 4096 Apr 11 2018 srv 19 dr-xr-xr-x 13 root root 0 Feb 18 10:24 sys 20 drwxrwxrwt. 8 root root 4096 Feb 19 03:11 tmp 21 drwxr-xr-x. 13 root root 4096 Feb 15 2019 usr 22 drwxr-xr-x. 20 root root 4096 May 27 2019 var
从第8行开始打印所有行
tail -n +8 ~/foo.txt
8 lrwxrwxrwx. 1 root root 7 Feb 15 2019 lib -> usr/lib 9 lrwxrwxrwx. 1 root root 9 Feb 15 2019 lib64 -> usr/lib64 10 drwx------. 2 root root 16384 Feb 15 2019 lost+found 11 drwxr-xr-x. 2 root root 4096 Apr 11 2018 media 12 drwxr-xr-x. 2 root root 4096 Apr 11 2018 mnt 13 drwxr-xr-x. 4 root root 4096 May 13 2019 opt 14 dr-xr-xr-x 88 root root 0 Apr 12 2020 proc 15 dr-xr-x---. 9 root root 4096 Feb 19 12:40 root 16 drwxr-xr-x 25 root root 740 Feb 4 14:08 run 17 lrwxrwxrwx. 1 root root 8 Feb 15 2019 sbin -> usr/sbin 18 drwxr-xr-x. 2 root root 4096 Apr 11 2018 srv 19 dr-xr-xr-x 13 root root 0 Feb 18 10:24 sys 20 drwxrwxrwt. 8 root root 4096 Feb 19 03:11 tmp 21 drwxr-xr-x. 13 root root 4096 Feb 15 2019 usr 22 drwxr-xr-x. 20 root root 4096 May 27 2019 var
打印来自标准输出的最后5行
cat ~/foo.txt | tail -n 5
18 drwxr-xr-x. 2 root root 4096 Apr 11 2018 srv 19 dr-xr-xr-x 13 root root 0 Feb 18 10:24 sys 20 drwxrwxrwt. 8 root root 4096 Feb 19 03:11 tmp 21 drwxr-xr-x. 13 root root 4096 Feb 15 2019 usr 22 drwxr-xr-x. 20 root root 4096 May 27 2019 var
实时滚动刷新
本示例会用到两个终端。 |
tail -f ~/bar.txt
这时终端1的屏幕上没有任何内容显示。
终端1保持打开状态,不要关闭
保持终端1和终端2,在终端2中反复执行以下命令:
echo `date "+%Y.%m.%d %M:%H:%S.%N"` >> ~/bar.txt
在终端2中反复执行3次命令后,终端1的屏幕内容结果如下:
2021.02.19 18:13:23.935206258
2021.02.19 18:13:23.935206258 2021.02.19 18:13:25.647371570
2021.02.19 18:13:23.935206258 2021.02.19 18:13:25.647371570 2021.02.19 18:13:26.607005345
可以看到终端1的屏幕内容一直在实时滚动刷新。
tail -f access.log 在查看网站访问日志记录时非常实用。
|
结束之后
删除临时文件:
rm -f ~/foo.txt ~/bar.txt
9.8. 打印到标准输出(cat)
cat
- 打印一个或多个文件的内容到标准输出
9.8.1. 基础用法
cat 文件名或路径
cat 文件名或路径 | 命令
- 常用参数
-n |
在行首添加行序号 |
--help |
帮助信息 |
9.8.2. 操作演示
开始之前
创建演示文件
echo 'foo.line1' > ~/foo.txt
echo 'foo.line2' >> ~/foo.txt
echo 'bar.line1' > ~/bar.txt
echo 'bar.line2' >> ~/bar.txt
打印文件内容
cat ~/foo.txt ~/bar.txt
foo.line1 foo.line2 bar.line1 bar.line2
打印时加上序号
cat -n ~/foo.txt ~/bar.txt
1 foo.line1 2 foo.line2 3 bar.line1 4 bar.line2
延伸:打印并排序文件内容
cat ~/foo.txt ~/bar.txt | sort
bar.line1 bar.line2 foo.line1 foo.line2
结束之后
删除临时文件:
rm -f ~/foo.txt ~/bar.txt
9.9. 打印第N列(cut)
cut
- 将行转为列,将指定列打印到标准输出
在Linux中处理数据时,分列和管道操作简直就是银弹,无敌的存在~ |
9.9.1. 基础用法
cut -d '分隔符' -f 列号 文件名或路径
命令 | cut -d '分隔符' -f 列号
- 常用参数
-d |
列分隔符 |
-f |
选中的列号列表,可以同时打印多列 |
--help |
帮助信息 |
9.9.2. 操作演示
在前面讲管道的章节,演示过复杂的命令:
ps aux | tail -n +2 | cut -d ' ' -f 1 | sort -u
“有没有简单又形象的例子”
“往下看……”
开始之前
网站日志分析是家常便饭,准备一些简化后的日志记录:
cat << EOF > ~/access.log
foo.com 80 118.118.47.239 [18/Feb/2021:23:22:23] "GET /360.html HTTP/1.1" 200
foo.com 80 115.202.80.105 [18/Feb/2021:23:22:24] "GET /login HTTP/1.1" 200
foo.com 80 123.6.49.36 [18/Feb/2021:23:22:24] "GET / HTTP/1.1" 200
foo.com 80 180.101.214.20 [18/Feb/2021:23:22:24] "GET /main.html HTTP/1.1" 200
foo.com 80 180.101.52.35 [18/Feb/2021:23:22:24] "GET /jquery.min.js HTTP/1.1" 200
foo.com 80 148.72.153.60 [18/Feb/2021:23:25:16] "GET /7.html HTTP/1.1" 200
foo.com 80 123.178.50.195 [18/Feb/2021:23:25:16] "GET /article/ HTTP/1.1" 200
EOF
仔细观察,看起来用空格分列就行了,试试~
打印日志记录的第1列
cut -d ' ' -f 1 ~/access.log
foo.com foo.com foo.com foo.com foo.com foo.com foo.com
打印日志记录的第1/3/5列
cut -d ' ' -f 1,3,5 ~/access.log
foo.com 118.118.47.239 "GET foo.com 115.202.80.105 "GET foo.com 123.6.49.36 "GET foo.com 180.101.214.20 "GET foo.com 180.101.52.35 "GET foo.com 148.72.153.60 "GET foo.com 123.178.50.195 "GET
打印日志记录的第3至4列
cut -d ' ' -f 3-4 ~/access.log
118.118.47.239 [18/Feb/2021:23:22:23] 115.202.80.105 [18/Feb/2021:23:22:24] 123.6.49.36 [18/Feb/2021:23:22:24] 180.101.214.20 [18/Feb/2021:23:22:24] 180.101.52.35 [18/Feb/2021:23:22:24] 148.72.153.60 [18/Feb/2021:23:25:16] 123.178.50.195 [18/Feb/2021:23:25:16]
打印日志记录的第1至5列
cut -d ' ' -f -5 ~/access.log
foo.com 80 118.118.47.239 [18/Feb/2021:23:22:23] "GET foo.com 80 115.202.80.105 [18/Feb/2021:23:22:24] "GET foo.com 80 123.6.49.36 [18/Feb/2021:23:22:24] "GET foo.com 80 180.101.214.20 [18/Feb/2021:23:22:24] "GET foo.com 80 180.101.52.35 [18/Feb/2021:23:22:24] "GET foo.com 80 148.72.153.60 [18/Feb/2021:23:25:16] "GET foo.com 80 123.178.50.195 [18/Feb/2021:23:25:16] "GET
打印日志记录的第5至最后1列
cut -d ' ' -f 5- ~/access.log
"GET /360.html HTTP/1.1" 200 "GET /login HTTP/1.1" 200 "GET / HTTP/1.1" 200 "GET /main.html HTTP/1.1" 200 "GET /jquery.min.js HTTP/1.1" 200 "GET /7.html HTTP/1.1" 200 "GET /article/ HTTP/1.1" 200
结束之后
删除临时文件:
rm -f ~/access.log
9.10. 显示当前进程(ps)
ps
- 显示当前运行的进程列表,常用于系统或程序排错
ps 命令功能强大、参数组合丰富,本文仅介绍基础功能。
|
作为了解系统运行状态的重要工具,ps 和 top 命令经常搭配使用。
|
9.10.1. 基础用法
ps -ef
ps -ef | grep python
- 常用参数
-e |
列出所有进程 |
-f |
显示进程命令行参数 |
--help all |
帮助信息 |
9.10.2. 操作演示
列出所有进程
ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 2020 ? 01:10:11 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0 0 2020 ? 00:00:00 [kthreadd]
root 3 2 0 2020 ? 00:14:11 [ksoftirqd/0]
root 5 2 0 2020 ? 00:00:00 [kworker/0:0H]
root 7 2 0 2020 ? 00:00:00 [migration/0]
root 8 2 0 2020 ? 00:00:00 [rcu_bh]
root 9 2 0 2020 ? 00:14:37 [rcu_sched]
root 10 2 0 2020 ? 00:00:00 [lru-add-drain]
root 11 2 0 2020 ? 00:03:14 [watchdog/0]
root 13 2 0 2020 ? 00:00:00 [kdevtmpfs]
root 14 2 0 2020 ? 00:00:00 [netns]
root 15 2 0 2020 ? 00:00:10 [khungtaskd]
......
过滤进程
ps
参数很多,不建议深入了解。直接用 grep
命令过滤输出结果为上策。
从输出结果中,找出包含 "python"
关键字的进程:
ps -ef | grep python
root 941 1 0 2020 ? 01:05:04 /usr/bin/python2 -Es /usr/sbin/tuned -l -P
root 31798 30406 0 15:17 pts/0 00:00:00 grep --color=auto python
root 32050 31982 0 2020 ? 00:00:00 /opt/eff.org/certbot/venv/bin/python /tmp/tmp.VxCfwAqjDj/pipstrap.py
ps -ef | grep python | grep -v 'grep' 可以过滤掉多余的 grep 。
|
9.11. 文本替换(sed)
sed
- 基于行的,用来过滤和转换文本的流编辑工具
sed
常用来替换每行中指定的字符串,非常方便。
其它功能不做介绍。
9.11.1. 基础用法
sed -i 's/old text/new text/g' 文件路径
- 常用参数
-i |
修改文件,不使用该参数时修改的内容会直接打印到屏幕 |
s///g
|
|
--help |
帮助信息 |
9.11.2. 操作演示
开始之前
cat << EOF > ~/word.txt
1,foobar
2,foo
3,qux
4,quux
5,quuz
EOF
为便于演示,以下操作移除了 |
将每行中第1个 "u"
替换为 "U"
sed 's/u/U/' word.txt
1,foobar
2,foo
3,qUx
4,qUux
5,qUuz
替换所有 "u"
为 "U"
sed 's/u/U/g' word.txt
1,foobar
2,foo
3,qUx
4,qUUx
5,qUUz
替换文 "qux"
为 "QUX"
sed 's/qux/QUX/g' word.txt
1,foobar
2,foo
3,QUX
4,quux
5,quuz
替换长度至少为3,并且以 "q"
开头的文本
sed 's/q../+++/g' word.txt
1,foobar
2,foo
3,+++
4,+++x
5,+++z
替换 "5"
开头,"z"
结尾的文本
sed 's/^5.*z/+/g' word.txt
1,foobar
2,foo
3,qux
4,quux
+
结束之后
删除临时文件:
rm -f ~/word.txt
9.12. 列数据组合(awk)
awk
- 基于行的,文本模式扫描和处理的迷你编程语言
常用 awk
将行数据分列组合,可生成新的数据结果。相比其它类似命令(如,sed
/ cut
),awk
更侧重列数据间的组合和拼接。
同样,awk
本文仅介绍基本用法。
不要尝试用 awk 完成复杂任务,用 Python 处理更加明智。
|
9.12.1. 基础用法
awk '{print $NF}' 文件路径
awk -F ':' '{print $1 " - " $(NF-1) " - " $NF}' 文件路径
- 常用参数
-F |
列分隔符,默认以空格分列 |
{ action } |
执行的动作
|
--help |
帮助信息 |
9.12.2. 操作演示
开始之前
head -n 10 /etc/group > ~/group.txt
打印第一列
awk -F ':' '{print $1}' ~/group.txt
root
bin
daemon
sys
adm
tty
disk
lp
mem
kmem
打印最后一列
awk -F ':' '{print $NF}' ~/group.txt
(空)
(空)
(空)
(空)
(空)
(空)
(空)
(空)
(空)
(空)
打印倒数第二列
awk -F ':' '{print $(NF-1)}' ~/group.txt
0
1
2
3
4
5
6
7
8
9
打印指定列,并用中横线分隔
awk -F ':' '{print $(NF-1) " - " $1}' ~/group.txt
0 - root
1 - bin
2 - daemon
3 - sys
4 - adm
5 - tty
6 - disk
7 - lp
8 - mem
9 - kmem
结束之后
删除临时文件:
rm -f ~/group.txt
9.13. 查看内存(free)
free
- 显示系统内存信息
9.13.1. 基础用法
free -h
free -m
- 常用参数
-h |
以人类友好格式显示内存信息 |
-m |
以Mib为单位显示内存信息 |
--help |
帮助信息 |
- 输出说明
total |
可用内存总量 |
used |
已经分配的内存(计算方式: |
free |
未分配的内存 |
shared |
(可忽略,无实际意义) |
buff/cache |
内核缓冲区、页面缓存和slab使用的内存数,必要时会分配给应用程序使用 |
available |
应用程序可直接使用的内存数(估计) |
Linux还剩多少内存可以给应用程序使用? 理想状态下,等于 |
9.13.2. 操作演示
人类友好格式显示
free -h
total used free shared buff/cache available Mem: 23G 13G 214M 88M 9.8G 9.5G Swap: 38G 1.2G 37G
Mib为单位显示
free -m
total used free shared buff/cache available Mem: 24066 13850 210 88 10005 9764 Swap: 39396 1274 38122
9.14. 查看硬盘空间(df)
df
- 显示文件系统硬盘空间使用量
9.14.1. 基础用法
df -h
df -hT
- 常用参数
-h |
以人类友好格式显示硬盘使用量 |
-T |
打印文件系统类型 |
--help |
帮助信息 |
- 输出说明
Filesystem |
存储设备或文件系统,通常指硬盘设备、硬盘分区、网络硬盘设备、系统设备等 |
Type |
存储设备的文件系统类型,如ext4、xfs等 |
Size |
设备或分区总容量 |
Used |
已用容量 |
Avail |
可用容量 |
Use% |
已用容量百分比 |
Mounted on |
挂载点 |
操作演示
人类友好格式显示
df -h
Filesystem Size Used Avail Use% Mounted on /dev/vda1 40G 34G 4.0G 90% / devtmpfs 486M 0 486M 0% /dev tmpfs 496M 0 496M 0% /dev/shm tmpfs 496M 472K 496M 1% /run tmpfs 496M 0 496M 0% /sys/fs/cgroup tmpfs 100M 0 100M 0% /run/user/0
显示文件系统类型
df -hT
Filesystem Type Size Used Avail Use% Mounted on /dev/vda1 ext4 40G 34G 4.0G 90% / devtmpfs devtmpfs 486M 0 486M 0% /dev tmpfs tmpfs 496M 0 496M 0% /dev/shm tmpfs tmpfs 496M 472K 496M 1% /run tmpfs tmpfs 496M 0 496M 0% /sys/fs/cgroup tmpfs tmpfs 100M 0 100M 0% /run/user/0
9.15. 文件格式转换(dos2unix)
dos2unix
- 用于将Windows格式的纯文本文件转为Linux格式
unix2dos
- 用于将Linux格式的纯文本文件转为Windows格式
以上两个命令常用于转换回车符(CR)和换行符(LF)互转。
Linux的文本文件中,换行符由单个换行符(LF)表示("\n"
)。
而Windows的文本文件中,换行符则由回车符(CR)和单个换行符(LF)表示("\r\n"
)。
9.15.1. 安装
yum install -y dos2unix unix2dos
9.15.2. 基础用法
dos2unix 文件路径
unix2dos 文件路径
无常用参数。
9.15.3. 操作演示
开始之前
echo -ne "Hello\r\nWorld\r\n" > ~/foo.txt
file ~/foo.txt
foo.txt: ASCII text, with CRLF line terminators
"CRLF"
表示文件使用 "\r\n"
换行。
转为Linux格式
dos2unix ~/foo.txt
dos2unix: converting file /root/foo.txt to Unix format ...
file ~/foo.txt
/root/foo.txt: ASCII text
转为Windows格式
unix2dos ~/foo.txt
unix2dos: converting file /root/foo.txt to DOS format ...
file ~/foo.txt
/root/foo.txt: ASCII text, with CRLF line terminators
结束之后
删除临时文件:
rm -f ~/foo.txt
9.16. 显示命令路径(which)
which
- 显示指定命令的完整路径
9.16.1. 基础用法
which 命令名称
无常用参数。
9.16.2. 操作演示
显示 ls
命令的路径
which ls
alias ls='ls --color=auto' /usr/bin/ls
显示 ll
命令的路径
which ll
alias ll='ls -l --color=auto' /usr/bin/ls
显示 mkdir
命令的路径
which mkdir
/usr/bin/mkdir
显示 sshd
命令的路径
which sshd
/usr/sbin/sshd
10. 内容搜索
10.1. 简介
前面已经提到过管道、cut
、awk
、sed
、sort
等等命令。
还没来得及最受欢迎的 grep
命令。grep
可以过滤出想要的字符串,也就是一个字符串搜索工具。
当 grep
、管道以及其它命令结合在一起时,可以大大提升使用Linux的幸福感。
10.2. 基础用法
10.2.1. 一个简单示例
搜索文件中的某个字符串,指定搜索关键字和文件名即可:
grep mail /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10.2.2. 忽略大小写
grep -i crond /var/log/cron
May 23 03:50:01 cdgeekcamp CROND[6603]: (root) CMD (/usr/lib64/sa/sa1 1 1) May 23 04:00:01 cdgeekcamp CROND[6610]: (root) CMD (/usr/lib64/sa/sa1 1 1) May 23 04:01:01 cdgeekcamp CROND[6617]: (root) CMD (run-parts /etc/cron.hourly) May 23 04:10:01 cdgeekcamp CROND[6630]: (root) CMD (/usr/lib64/sa/sa1 1 1) May 23 04:20:01 cdgeekcamp CROND[6638]: (root) CMD (/usr/lib64/sa/sa1 1 1) May 23 04:30:01 cdgeekcamp CROND[6645]: (root) CMD (/usr/lib64/sa/sa1 1 1) May 23 04:40:01 cdgeekcamp CROND[6652]: (root) CMD (/usr/lib64/sa/sa1 1 1) May 23 04:50:01 cdgeekcamp CROND[6660]: (root) CMD (/usr/lib64/sa/sa1 1 1) May 23 05:00:01 cdgeekcamp CROND[6669]: (root) CMD (/usr/lib64/sa/sa1 1 1) May 23 05:01:01 cdgeekcamp CROND[6676]: (root) CMD (run-parts /etc/cron.hourly)
10.2.3. 反向匹配
grep -v 'run-parts /etc/cron.hourly' /var/log/cron
关键字包含空格时,必须用单引号或双引号包起来。 |
May 23 03:42:01 cdgeekcamp run-parts(/etc/cron.daily)[6576]: finished logrotate May 23 03:42:01 cdgeekcamp run-parts(/etc/cron.daily)[6559]: starting man-db.cron May 23 03:42:01 cdgeekcamp run-parts(/etc/cron.daily)[6587]: finished man-db.cron May 23 03:42:01 cdgeekcamp run-parts(/etc/cron.daily)[6559]: starting mlocate May 23 03:42:01 cdgeekcamp run-parts(/etc/cron.daily)[6598]: finished mlocate May 23 03:42:01 cdgeekcamp anacron[6534]: Job `cron.daily' terminated May 23 03:42:01 cdgeekcamp anacron[6534]: Normal exit (1 job run) May 23 03:50:01 cdgeekcamp CROND[6603]: (root) CMD (/usr/lib64/sa/sa1 1 1) May 23 04:00:01 cdgeekcamp CROND[6610]: (root) CMD (/usr/lib64/sa/sa1 1 1) May 23 04:01:01 cdgeekcamp run-parts(/etc/cron.hourly)[6617]: starting 0anacron May 23 04:01:01 cdgeekcamp run-parts(/etc/cron.hourly)[6626]: finished 0anacron
10.3. 搜索目录下文件的内容
grep -r -i crond /var/log/
或
grep -ri crond /var/log/
/var/log/cron-20210509:May 2 03:10:01 cdgeekcamp CROND[22917]: (root) CMD (/usr/lib64/sa/sa1 1 1) /var/log/cron-20210509:May 2 03:20:01 cdgeekcamp CROND[23403]: (root) CMD (/usr/lib64/sa/sa1 1 1) /var/log/cron-20210509:May 2 03:30:01 cdgeekcamp CROND[23889]: (root) CMD (/usr/lib64/sa/sa1 1 1) /var/log/cron-20210509:May 2 03:40:01 cdgeekcamp CROND[24375]: (root) CMD (/usr/lib64/sa/sa1 1 1) /var/log/cron-20210509:May 2 03:50:01 cdgeekcamp CROND[24862]: (root) CMD (/usr/lib64/sa/sa1 1 1) ...... /var/log/audit/audit.log.1:type=USER_ACCT msg=audit(1620024001.562:647420): pid=29877 uid=0 auid=4294967295 ses=4294967295 msg='op=PAM:accounting grantors=pam_access,pam_unix,pam_localuser acct="root" exe="/usr/sbin/crond" hostname=? addr=? terminal=cron res=success' /var/log/audit/audit.log.1:type=CRED_ACQ msg=audit(1620024001.562:647421): pid=29877 uid=0 auid=4294967295 ses=4294967295 msg='op=PAM:setcred grantors=pam_env,pam_unix acct="root" exe="/usr/sbin/crond" hostname=? addr=? terminal=cron res=success'
10.4. 搜索结果计数
grep
能做搜索过滤,还可以输出数字或计数信息。
10.4.1. 统计文本在文件中出现多少次
grep -c cron.hourly /var/log/cron
318
文本 "cron.hourly"
在文件中出现 "318"
次。
10.4.2. 打印行号
grep -n cron.hourly /var/log/cron
10:May 23 04:01:01 cdgeekcamp CROND[6617]: (root) CMD (run-parts /etc/cron.hourly) 11:May 23 04:01:01 cdgeekcamp run-parts(/etc/cron.hourly)[6617]: starting 0anacron 12:May 23 04:01:01 cdgeekcamp run-parts(/etc/cron.hourly)[6626]: finished 0anacron 19:May 23 05:01:01 cdgeekcamp CROND[6676]: (root) CMD (run-parts /etc/cron.hourly) 20:May 23 05:01:01 cdgeekcamp run-parts(/etc/cron.hourly)[6676]: starting 0anacron 21:May 23 05:01:01 cdgeekcamp run-parts(/etc/cron.hourly)[6685]: finished 0anacron 28:May 23 06:01:01 cdgeekcamp CROND[6733]: (root) CMD (run-parts /etc/cron.hourly) 29:May 23 06:01:01 cdgeekcamp run-parts(/etc/cron.hourly)[6733]: starting 0anacron 30:May 23 06:01:01 cdgeekcamp run-parts(/etc/cron.hourly)[6742]: finished 0anacron ......(省略部分内容)
每行的第一个数字表示行号。
10.4.3. 打印前N行内容,带上行号
打印前5行结果:
grep -n -m 5 cron.hourly /var/log/cron
10:May 23 04:01:01 cdgeekcamp CROND[6617]: (root) CMD (run-parts /etc/cron.hourly) 11:May 23 04:01:01 cdgeekcamp run-parts(/etc/cron.hourly)[6617]: starting 0anacron 12:May 23 04:01:01 cdgeekcamp run-parts(/etc/cron.hourly)[6626]: finished 0anacron 19:May 23 05:01:01 cdgeekcamp CROND[6676]: (root) CMD (run-parts /etc/cron.hourly) 20:May 23 05:01:01 cdgeekcamp run-parts(/etc/cron.hourly)[6676]: starting 0anacron
10.5. 输出匹配位置的上下内容
想看看搜索关键字前后的内容,用 "-A"
、"-B"
和 "-C"
三个选项就行。
10.5.1. "/etc/passwd"
文件部分内容
games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin
在开始之前,留意下
nobody:x:99:99:Nobody:/:/sbin/nologin
前后的内容。
10.5.2. 打印匹配文本的行及其前面N行
找出包含 "nobody:"
的行,同时匹配行的前2行内容(共3行):
grep -B 2 'nobody:' /etc/passwd
games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin
10.5.3. 打印匹配文本的行及其后面N行
找出包含 "nobody:"
的行,同时匹配行的后2行内容(共3行):
grep -A 2 'nobody:' /etc/passwd
nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin
10.5.4. 打印匹配文本的行及其前后N行
找出包含 "nobody:"
的行,同时匹配行的前后2行内容(共5行):
grep -C 2 'nobody:' /etc/passwd
games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin
10.6. 使用正则表达式
现在你对 grep
的了解已经可以应付大多数情况,搜索关键字、搜索目录下的内容、结果计数甚至显示结果前后内容都不在话下。
这些都是在关键字明确的前提下。万一某天想搜索关键字的一部分,你该怎么做?又或者,需要更加复杂的搜索操作呢?
grep
结合正则表达式(grep -E
)做搜索,就完事儿。
习惯简写成 egrep
。
10.6.1. 行首行尾匹配
打印以字母 "n"
开头的行:
grep '^n' /etc/passwd
nobody:x:99:99:Nobody:/:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin nscd:x:28:28:NSCD Daemon:/:/sbin/nologin nginx:x:997:995:nginx user:/var/cache/nginx:/sbin/nologin
打印以字母 "h"
结尾的行:
grep 'h$' /etc/passwd
root:x:0:0:root:/root:/bin/bash www:x:1001:1001::/var/lib/www:/bin/bash
10.6.2. 字符串匹配
打印以字母 "t"
开头,字母 "n"
结尾的行:
egrep '^t.*n$' /etc/passwd
tcpdump:x:72:72::/:/sbin/nologin tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin tomcat:x:53:53:Apache Tomcat:/usr/share/tomcat:/sbin/nologin
10.6.3. egrep
支持的正则表达式
一点点准备
创建一个测试数据文件:
cat << EOF > ~/access.log
foo.org 80 118.118.47.239 [18/Jan/2021:01:00:23] "GET /360.html HTTP/1.1" 200
bar.org 8080 115.202.80.105 [19/Feb/2021:02:12:24] "POST /login HTTP/1.1" 404
qux.com 80 123.6.49.36 [20/Mar/2021:03:22:24] "GET / HTTP/1.1" 200
quux.com 80 180.101.214.20 [21/Apr/2021:04:15:24] "GET /main.html HTTP/1.1" 200
quz.io 8080 180.101.52.35 [21/Aug/2021:13:18:24] "GET /log.jpg HTTP/1.1" 200
quuz.cn 8080 180.101.52.35 [21/Aug/2021:13:18:24] "GET /jquery.min.js HTTP/1.1" 403
quuuz.cn 8080 125.64.14.56 [21/Aug/2021:13:18:24] "GET /load.js HTTP/1.1" 200
corge.com 80 148.72.153.60 [22/May/2021:23:25:16] "GET /7.html HTTP/1.1" 500
garply.net 80 123.178.50.195 [23/Oct/2021:23:50:16] "POST /article/ HTTP/1.1" 301
garply.net 80 123.178.50.195 [23/Oct/2021:23:50:16] "POST /article_new/ HTTP/1.1" 200
EOF
在下文看到 egrep '正则表达式' ~/access.log 这样的命令时,复制到终端试一试。动手效果更好!
|
基础操作符
小原点 '.'
用作正则表达式符号时,表示匹配任意字符,'b'
、'x'
、'0'
等等都没问题。
匹配常见字符串是最基础的正则表达式,如 aa、0、.?、.{1,2} 等等。
大部分字符(包括大小写字母、数字)作表达式都表示自身(所见即所得)。比如,0 匹配数字零,aa 匹配两个小写字母a。
a. 能够匹配长度为2的行,第一个字符必须是小写字母 'a'
,第二个可以是任意字符,'a1'
、'ab'
、'a,'
都符合规则。
只匹配一个小写字母a和一个小原点('a.'
)则用 a\., \. 表示一个小原点本身。相反,. 表示匹配任意字符。
也就是说,表达式符号前多加一个斜杠表示字符本身,称作字符转义。
以下操作符号可以限定在匹配时,某个字符可以出现多少次:
操作符 | 说明 | 示例 |
---|---|---|
? |
匹配0次或1次 |
|
* |
匹配0次或多次 |
|
+ |
匹配至少1次 |
|
{n} |
只匹配n次 |
|
{n,} |
匹配至少n次 |
|
{,m} |
匹配最多m次 |
|
{n,m} |
匹配至少n次,最多m次 |
|
上面这些单表达式匹配的例子挺OK的,那同时找出包含 'article_' 和 'qux' 的行怎么做?
一个中竖线和一对圆括号连接多个表达式,轻松完成多表达式查找匹配:
egrep '(article_+)|(qux)' ~/access.log
qux.com 80 123.6.49.36 [20/Mar/2021:03:22:24] "GET / HTTP/1.1" 200 garply.net 80 123.178.50.195 [23/Oct/2021:23:50:16] "POST /article_new/ HTTP/1.1" 200
| 前后不能有空格。 |
更多 egrep
支持的正则表达式内容,请阅读 egrep正则表达式扩展 。
egrep
支持的缩写
一个斜杠后紧跟某些普通字符时,具有特殊的含义:
\w |
匹配英文单词,通常单词由下划线、大小写字母和数字组成,等同 [_[:alnum:]]。 |
|
\W |
匹配非英文单词,也就是匹配下划线、大小写字母和数字以外的字符,等同 [^_[:alnum:]]。 |
|
\s |
匹配空格, 等同 [[:space:]]。 |
|
\S |
匹配非空格, 等同 [^[:space:]]。 |
|
动动手,练习一个多表达式的例子:
egrep '\w+\s' ~/access.log
匹配至少一个英文单词字符,并且紧跟一个空格的行。你会看到类似这样的输出结果:
garply.net 80 123.178.50.195 [23/Oct/2021:23:50:16] "POST /article_new/ HTTP/1.1" 200
egrep
的限制
egrep
的在功能实现时,对特定的表达式有限制。
会经常遇到中横线开头的表达式提示有错误,错误示范如下:
egrep '-foo' ~/access.log
grep: oo: No such file or directory
正确的示范:
egrep '\-foo' ~/access.log
记住,表达式不能用中横线(-)开头,必须加转义后才行。
更多其它的限制,万年遇不到,直接略过~
10.7. grep和管道
Linux的两大神技 grep
和管道结合,才是使用频率最高的。
看看这个例子:
grep 'Accepted' /var/log/secure | cut -d ' ' -f 9,11 | sort -u
git 171.221.150.93 git 182.138.181.132 root 171.221.150.93 root 182.138.181.132
换个写法:
cat /var/log/secure | grep 'Accepted' | cut -d ' ' -f 9,11 | sort -u
输出结果和上面是一样的。
再来一个新花样:
cat /var/log/secure | grep 'Accepted' | awk '{print "User:"$9", Login IP address:"$11}' | sort -u
或
cat /var/log/secure | egrep 'Accep\w+' | awk '{print "User:"$9", Login IP address:"$11}' | sort -u
User:git, Login IP address:171.221.150.93 User:git, Login IP address:182.138.181.132 User:root, Login IP address:171.221.150.93 User:root, Login IP address:182.138.181.132
grep
可以直接查找文件中的内容,也可以直接查找管道前面(标准输出)的内容。
再结合 "-rni"
之类的参数, 让 grep
变成几乎万能的文件内容查找工具。
用过的人都说好!
11. 文件定位
11.1. 简介
安装软件后,怎么快速找出配置文件路径?
想不起自己安装的软件到哪儿去了?
不需要复杂的操作,用 locate
和 find
命令几秒钟解决文件搜索问题。
locate
在文件索引(不需要实时读取目录)中搜索指定文件名,搜索速度很快。Windows软件 Everything 和 locate
功能实现非常类似。
find
实时搜索指定目录中的文件名,搜索速度取决于硬盘速度。
两个命令用途相似,明确要查找某个目录下的文件时用 find
,其它情况建议无脑 locate
。
11.2. locate
locate
命令是软件 mlocate
的一部分,locate
在文件索引中搜索指定文件名。
mlocate
还有一个 updatedb
命令,负责更新文件索引。
11.2.1. 安装mlocate
安装mlocate软件包:
yum install -y mlocate
首次更新文件索引:
updatedb
默认情况下,CentOS计划任务会每天自动更新一次(执行一次 updatedb
命令)文件索引。
如果当前新安装了软件或上传了文件到CentOS,需要手动执行 updatedb
。然后,locate
才能找到新文件。
在增加文件、删除文件后,使用 locate 前记得先 updatedb 。
|
P.S. updatedb
可以执行无数次,不要有心理负担~
11.2.2. 示例
搜索包含 "linux"
和 "signal.h"
关键字的文件路径:
locate signal.h | grep linux
/usr/include/linux/signal.h
搜索ssh服务相关的配置文件路径(必须同时包含 "config"
和 "etc"
):
locate -b ssh | grep config | grep etc
/etc/ssh/ssh_config /etc/ssh/sshd_config /etc/sysconfig/sshd
-b
参数表示只搜索文件名部分(如 "ssh_config"
、"sshd_config"
、"sshd"
等等),不搜索路径中的字符串。
用正则表达式搜索所有日志文件(以 ".log"
扩展名结尾的文件路径):
locate -r '\.log$'
/usr/lib/rpm/rpm.log /var/log/boot.log /var/log/mysqld.log /var/log/yum.log /var/log/audit/audit.log ......
-r
参数表示使用正则表达式搜索,注意必须用单引号包住表达式。
搜索 "ssh"
相关的 "service"
文件:
locate .service | grep ssh
或
locate -r 'ssh.*service'
/etc/systemd/system/multi-user.target.wants/sshd.service /usr/lib/systemd/system/sshd-keygen.service /usr/lib/systemd/system/sshd.service /usr/lib/systemd/system/sshd@.service
11.3. find
find
命令属于系统自带的,不需要安装。
为和 locate
对比,以下示例和之前相同。
注意对比 find 命令和 locate 的执行速度。
|
11.3.1. 示例
搜索包含 "linux"
和 "signal.h"
关键字的文件路径:
find / | grep signal.h | grep linux
/usr/include/linux/signal.h
搜索ssh服务相关的配置文件路径(必须同时包含 "config"
和 "etc"
):
find / | grep ssh | grep config | grep etc
/etc/ssh/ssh_config /etc/ssh/sshd_config /etc/sysconfig/sshd
用正则表达式搜索所有日志文件(以 ".log"
扩展名结尾的文件路径):
find / -name '*.log'
/usr/lib/rpm/rpm.log /var/log/boot.log /var/log/mysqld.log /var/log/yum.log /var/log/audit/audit.log ......
-name
参数表示只搜索文件名部分(如 "rpm.log"
、"boot.log"
等等),不搜索路径中的字符串。
搜索 "ssh"
相关的 "service"
文件:
find / -name '*.service' | grep ssh
/sys/fs/cgroup/systemd/system.slice/sshd.service /etc/systemd/system/multi-user.target.wants/sshd.service /usr/lib/systemd/system/sshd@.service /usr/lib/systemd/system/sshd.service /usr/lib/systemd/system/sshd-keygen.service
上面的
/sys/fs/cgroup/systemd/system.slice/sshd.service
用 locate
是不会有的。因为 locate
会忽略类似 "/tmp"
、"/proc"
、"/sys"
之类的系统临时目录。
12. 软件包管理
12.1. 简介
yum是基于RPM的包管理器( ".rpm"
格式文件),可以从网络仓库查询、下载软件包,安装并升级系统至最新版。当然,移除软件包也是可以的。
yum会扫描软件的依赖关系,自动检测、下载并安装相关软件。不需要搜索官网下载软件安装包,不需要手动解决软件安装环境依赖。
yum可以配置外部(网络软件)仓库或源代码仓库,提供许多内置插件来增强和扩展功能。比如,增加第三方仓库、启用禁用仓库、设置网络代理等。
12.2. 安装
12.2.1. 基础用法
yum install -y 软件包名称或路径
- 常用参数
y |
表示 |
12.2.2. 从仓库安装
yum install -y tree
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile Resolving Dependencies --> Running transaction check ---> Package tree.x86_64 0:1.6.0-10.el7 will be installed --> Finished Dependency Resolution Dependencies Resolved ========================================================= Package Arch Version Repository Size ========================================================= Installing: tree x86_64 1.6.0-10.el7 base 46 k Transaction Summary ========================================================= Install 1 Package Total download size: 46 k Installed size: 87 k Downloading packages: tree-1.6.0-10.el7.x86_64.rpm | 46 kB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : tree-1.6.0-10.el7.x86_64 1/1 Verifying : tree-1.6.0-10.el7.x86_64 1/1 Installed: tree.x86_64 0:1.6.0-10.el7 Complete!
12.2.3. 从URL安装
yum install -y https://mirrors.163.com/centos/7/os/x86_64/Packages/tree-1.6.0-10.el7.x86_64.rpm
Loaded plugins: fastestmirror tree-1.6.0-10.el7.x86_64.rpm | 46 kB 00:00:00 Examining /var/tmp/yum-root-kombYG/tree-1.6.0-10.el7.x86_64.rpm: tree-1.6.0-10.el7.x86_64 Marking /var/tmp/yum-root-kombYG/tree-1.6.0-10.el7.x86_64.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package tree.x86_64 0:1.6.0-10.el7 will be installed --> Finished Dependency Resolution Dependencies Resolved ========================================================================================= Package Arch Version Repository Size ========================================================================================= Installing: tree x86_64 1.6.0-10.el7 /tree-1.6.0-10.el7.x86_64 87 k Transaction Summary ========================================================================================= Install 1 Package Total size: 87 k Installed size: 87 k Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : tree-1.6.0-10.el7.x86_64 1/1 Verifying : tree-1.6.0-10.el7.x86_64 1/1 Installed: tree.x86_64 0:1.6.0-10.el7 Complete!
12.2.4. 从本地安装
wget https://mirrors.163.com/centos/7/os/x86_64/Packages/tree-1.6.0-10.el7.x86_64.rpm -O ~/tree-1.6.0-10.el7.x86_64.rpm
--2021-05-11 16:09:58-- https://mirrors.163.com/centos/7/os/x86_64/Packages/tree-1.6.0-10.el7.x86_64.rpm Resolving mirrors.163.com (mirrors.163.com)... 101.6.8.193, 2402:f000:1:408:8100::1 Connecting to mirrors.163.com (mirrors.163.com)|101.6.8.193|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 47508 (46K) [application/x-redhat-package-manager] Saving to: ‘/root/tree-1.6.0-10.el7.x86_64.rpm’ 100%[===================================================================>] 47,508 --.-K/s in 0.03s 2021-05-11 16:09:59 (1.67 MB/s) - ‘/root/tree-1.6.0-10.el7.x86_64.rpm’ saved [47508/47508]
yum install -y ~/tree-1.6.0-10.el7.x86_64.rpm
Loaded plugins: fastestmirror Examining /root/tree-1.6.0-10.el7.x86_64.rpm: tree-1.6.0-10.el7.x86_64 Marking /root/tree-1.6.0-10.el7.x86_64.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package tree.x86_64 0:1.6.0-10.el7 will be installed --> Finished Dependency Resolution Dependencies Resolved ========================================================================================= Package Arch Version Repository Size ========================================================================================= Installing: tree x86_64 1.6.0-10.el7 /tree-1.6.0-10.el7.x86_64 87 k Transaction Summary ========================================================================================= Install 1 Package Total size: 87 k Installed size: 87 k Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : tree-1.6.0-10.el7.x86_64 1/1 Verifying : tree-1.6.0-10.el7.x86_64 1/1 Installed: tree.x86_64 0:1.6.0-10.el7 Complete!
使用 yum 会自动检测软件包依赖关系,从网络下载,自动安装依赖。
|
12.4. 查询
12.4.1. 基础用法
yum list [软件包名称或星号表达式]
yum list installed [软件包名称或星号表达式]
yum list available [软件包名称或星号表达式]
yum info 软件包名称
12.4.2. 列出所有软件包
yum list
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile Installed Packages GeoIP.x86_64 1.5.0-13.el7 @anaconda NetworkManager.x86_64 1:1.12.0-10.el7_6 @updates ......(省略部分内容)...... Available Packages 0ad.x86_64 0.0.22-1.el7 epel 0ad-data.noarch 0.0.22-1.el7 epel 0install.x86_64 2.11-1.el7 epel ......(省略部分内容)......
12.4.3. 列出已经安装的软件包
yum list installed
Loaded plugins: fastestmirror Installed Packages GeoIP.x86_64 1.5.0-13.el7 @anaconda NetworkManager.x86_64 1:1.12.0-10.el7_6 @updates NetworkManager-libnm.x86_64 1:1.12.0-10.el7_6 @updates NetworkManager-team.x86_64 1:1.12.0-10.el7_6 @updates NetworkManager-tui.x86_64 1:1.12.0-10.el7_6 @updates ......(省略部分内容)......
12.4.4. 列出仓库中可用的软件包
yum list available
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile Available Packages 0ad.x86_64 0.0.22-1.el7 epel 0ad-data.noarch 0.0.22-1.el7 epel 0install.x86_64 2.11-1.el7 epel 2048-cli.x86_64 0.9.1-1.el7 epel 2048-cli-nocurses.x86_64 0.9.1-1.el7 epel ......(省略部分内容)......
12.4.5. 仅显示指定名称的软件包
yum list
命令可以在尾部添加软件包名称(支持星号模糊匹配),命令输出结果中只会显示名称相关的软件包。
星号占位符表示任意字符会出现一次以上(含一次)。 |
显示软件包名称中包含 "openssh"
字样的结果:
yum list *openssh*
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile Installed Packages openssh.x86_64 7.4p1-16.el7 @anaconda openssh-clients.x86_64 7.4p1-16.el7 @anaconda openssh-server.x86_64 7.4p1-16.el7 @anaconda Available Packages gsi-openssh.x86_64 7.4p1-6.el7 epel gsi-openssh-clients.x86_64 7.4p1-6.el7 epel gsi-openssh-server.x86_64 7.4p1-6.el7 epel lxqt-openssh-askpass.x86_64 0.14.1-3.el7 epel lxqt-openssh-askpass-l10n.noarch 0.11.2-3.el7 epel lxqt-openssh-askpass-l10n.x86_64 0.14.1-3.el7 epel openssh.x86_64 7.4p1-21.el7 base openssh-askpass.x86_64 7.4p1-21.el7 base openssh-cavs.x86_64 7.4p1-21.el7 base openssh-clients.x86_64 7.4p1-21.el7 base openssh-keycat.x86_64 7.4p1-21.el7 base openssh-ldap.x86_64 7.4p1-21.el7 base openssh-ldap-authkeys.noarch 0.1.0~git20200205.aee4c46-2.el7 epel openssh-server.x86_64 7.4p1-21.el7 base openssh-server-sysvinit.x86_64 7.4p1-21.el7 base perl-Net-OpenSSH.noarch 0.62-1.el7 epel
可以试一试 |
去掉命令中的第一个或第二个星号,输出结果会明显不同。 |
12.4.6. 查看软件包信息
yum info tree
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile Installed Packages Name : tree Arch : x86_64 Version : 1.6.0 Release : 10.el7 Size : 87 k Repo : installed Summary : File system tree viewer URL : http://mama.indstate.edu/users/ice/tree/ License : GPLv2+ Description : The tree utility recursively displays the contents of directories in a : tree-like format. Tree is basically a UNIX port of the DOS tree : utility.
12.5. 查询(rpm)
除 yum
命令外,还可以使用更基础的 rpm
命令查询软件包信息。
rpm 仅对已经安装的软件包有效。
|
12.5.1. 列出已经安装的包
rpm -qa
authconfig-6.2.8-30.el7.x86_64
kbd-legacy-1.15.5-15.el7.noarch
usermode-1.111-5.el7.x86_64
ncurses-base-5.9-14.20130511.el7_4.noarch
trousers-0.3.14-2.el7.x86_64
chrony-3.2-2.el7.x86_64
......
......
......
12.5.2. 查询文件属于哪个包
rpm -qf /usr/sbin/sshd
openssh-server-7.4p1-16.el7.x86_64
12.5.3. 列出包中的文件
rpm -ql openssh-server
或
rpm -ql openssh-server-7.4p1-16.el7.x86_64
/etc/pam.d/sshd
/etc/ssh/sshd_config
/etc/sysconfig/sshd
/usr/lib/systemd/system/sshd-keygen.service
/usr/lib/systemd/system/sshd.service
/usr/lib/systemd/system/sshd.socket
/usr/lib/systemd/system/sshd@.service
/usr/lib64/fipscheck/sshd.hmac
/usr/libexec/openssh/sftp-server
/usr/sbin/sshd
/usr/sbin/sshd-keygen
/usr/share/man/man5/moduli.5.gz
/usr/share/man/man5/sshd_config.5.gz
/usr/share/man/man8/sftp-server.8.gz
/usr/share/man/man8/sshd.8.gz
/var/empty/sshd
12.5.4. 列出包中的配置文件
rpm -qc openssh-server
或
rpm -qc openssh-server-7.4p1-16.el7.x86_64
/etc/pam.d/sshd
/etc/ssh/sshd_config
/etc/sysconfig/sshd
12.5.5. 列出包中文件的状态
rpm -qs openssh-server
normal /etc/pam.d/sshd
normal /etc/ssh/sshd_config
normal /etc/sysconfig/sshd
normal /usr/lib/systemd/system/sshd-keygen.service
normal /usr/lib/systemd/system/sshd.service
normal /usr/lib/systemd/system/sshd.socket
normal /usr/lib/systemd/system/sshd@.service
normal /usr/lib64/fipscheck/sshd.hmac
normal /usr/libexec/openssh/sftp-server
normal /usr/sbin/sshd
normal /usr/sbin/sshd-keygen
normal /usr/share/man/man5/moduli.5.gz
normal /usr/share/man/man5/sshd_config.5.gz
normal /usr/share/man/man8/sftp-server.8.gz
normal /usr/share/man/man8/sshd.8.gz
normal /var/empty/sshd
12.6. 升级
12.6.1. 基础用法
yum update -y [软件包名称或星号表达式]
- 常用参数
y |
表示 |
12.6.2. 升级所有软件包
从网络仓库获取最新的软件包信息,下载并更新系统:
yum update -y
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile Resolving Dependencies --> Running transaction check ---> Package GeoIP.x86_64 0:1.5.0-13.el7 will be updated ---> Package GeoIP.x86_64 0:1.5.0-14.el7 will be an update --> Processing Dependency: geoipupdate for package: GeoIP-1.5.0-14.el7.x86_64 ---> Package NetworkManager.x86_64 1:1.12.0-10.el7_6 will be updated ---> Package NetworkManager.x86_64 1:1.18.8-2.el7_9 will be an update ......(省略部分内容)...... --> Running transaction check ---> Package bind-export-libs.x86_64 32:9.11.4-26.P2.el7_9.5 will be installed ---> Package geoipupdate.x86_64 0:2.5.0-1.el7 will be installed --> Finished Dependency Resolution --> Running transaction check ---> Package kernel.x86_64 0:3.10.0-957.el7 will be erased --> Finished Dependency Resolution Dependencies Resolved ============================================================================= Package Arch Version Repository Size ============================================================================= Installing: iwl7260-firmware noarch 25.30.13.0-80.el7_9 updates 6.1 M replacing iwl7265-firmware.noarch 22.0.7.0-69.el7 kernel x86_64 3.10.0-1160.25.1.el7 updates 50 M kernel-devel x86_64 3.10.0-1160.25.1.el7 updates 18 M Updating: GeoIP x86_64 1.5.0-14.el7 base 1.5 M NetworkManager x86_64 1:1.18.8-2.el7_9 updates 1.9 M ......(省略部分内容)...... ============================================================================= Install 3 Packages (+2 Dependent packages) Upgrade 265 Packages Remove 1 Package Total download size: 407 M ......(省略部分内容)...... Complete!
12.6.3. 升级一个或多个软件包
yum update -y vim openssh*
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile Resolving Dependencies --> Running transaction check ---> Package openssh.x86_64 0:7.4p1-16.el7 will be updated ......(省略部分内容)...... ---> Package vim-common.x86_64 2:7.4.160-6.el7_6 will be updated ---> Package vim-common.x86_64 2:7.4.629-8.el7_9 will be an update --> Finished Dependency Resolution Dependencies Resolved ================================================================== Package Arch Version Repository Size ================================================================== Updating: openssh x86_64 7.4p1-21.el7 base 510 k openssh-clients x86_64 7.4p1-21.el7 base 655 k openssh-server x86_64 7.4p1-21.el7 base 459 k vim-enhanced x86_64 2:7.4.629-8.el7_9 updates 1.1 M Updating for dependencies: vim-common x86_64 2:7.4.629-8.el7_9 updates 5.9 M Transaction Summary ================================================================== Upgrade 4 Packages (+1 Dependent package) Total size: 8.6 M Total download size: 1.6 M ......(省略部分内容)...... Complete!
12.7. 移除
12.7.1. 基础用法
yum erase 软件包名称
为防止误操作,不建议使用 -y 参数或者星号表达式。
|
12.7.2. 从系统移除软件包
yum erase tree
Loaded plugins: fastestmirror Resolving Dependencies --> Running transaction check ---> Package tree.x86_64 0:1.6.0-10.el7 will be erased --> Finished Dependency Resolution Dependencies Resolved ============================================================================== Package Arch Version Repository Size ============================================================================== Removing: tree x86_64 1.6.0-10.el7 installed 87 k Transaction Summary ============================================================================== Remove 1 Package Installed size: 87 k Is this ok [y/N]: y Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Erasing : tree-1.6.0-10.el7.x86_64 1/1 Verifying : tree-1.6.0-10.el7.x86_64 1/1 Removed: tree.x86_64 0:1.6.0-10.el7 Complete!
12.8. 下载
12.8.1. 基础用法
yum install --downloadonly --downloaddir=下载目录 [软件包名称或星号表达式]
yumdownloader [软件包名称或星号表达式]
yumdownloader --resolve [软件包名称或星号表达式]
yumdownloader --urls --resolve [软件包名称或星号表达式]
- 常用参数
downloadonly |
不安装,仅下载软件包文件及其依赖的软件包 |
downloaddir |
软件包文件的下载目录 |
urls |
仅打印软件包的下载地址,不下载 |
resolve |
检查软件包依赖关系并下载 |
12.8.2. 下载软件包文件方法一:yum
下载软件包文件,保存在 /tmp
目录下:
yum install --downloadonly --downloaddir=/tmp vim
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile Resolving Dependencies --> Running transaction check ---> Package vim-enhanced.x86_64 2:7.4.160-6.el7_6 will be updated ---> Package vim-enhanced.x86_64 2:7.4.629-8.el7_9 will be an update --> Processing Dependency: vim-common = 2:7.4.629-8.el7_9 for package: 2:vim-enhanced-7.4.629-8.el7_9.x86_64 --> Running transaction check ---> Package vim-common.x86_64 2:7.4.160-6.el7_6 will be updated ---> Package vim-common.x86_64 2:7.4.629-8.el7_9 will be an update --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================ Package Arch Version Repository Size ============================================================================================================ Updating: vim-enhanced x86_64 2:7.4.629-8.el7_9 updates 1.1 M Updating for dependencies: vim-common x86_64 2:7.4.629-8.el7_9 updates 5.9 M Transaction Summary ============================================================================================================ Upgrade 1 Package (+1 Dependent package) Total size: 7.0 M Background downloading packages, then exiting: exiting because "Download Only" specified
查看下载的软件包文件:
[root@cdgeekcamp ~]# ll /tmp/vim* -rw-r--r-- 1 root root 6205700 Dec 18 04:37 /tmp/vim-common-7.4.629-8.el7_9.x86_64.rpm -rw-r--r-- 1 root root 1106008 Dec 18 04:37 /tmp/vim-enhanced-7.4.629-8.el7_9.x86_64.rpm
12.8.3. 下载软件包文件方法二:yumdownloader
安装 yumdownloader
工具:
yum install -y yum-utils
查看包及其依赖关系的下载地址:
yumdownloader --urls --resolve vim
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile --> Running transaction check ---> Package vim-enhanced.x86_64 2:7.4.629-8.el7_9 will be installed --> Processing Dependency: vim-common = 2:7.4.629-8.el7_9 for package: 2:vim-enhanced-7.4.629-8.el7_9.x86_64 --> Running transaction check ---> Package vim-common.x86_64 2:7.4.160-6.el7_6 will be updated --> Processing Dependency: vim-common = 2:7.4.160-6.el7_6 for package: 2:vim-enhanced-7.4.160-6.el7_6.x86_64 ---> Package vim-common.x86_64 2:7.4.629-8.el7_9 will be an update --> Running transaction check ---> Package vim-enhanced.x86_64 2:7.4.160-6.el7_6 will be updated --> Finished Dependency Resolution http://mirrors.cloud.aliyuncs.com/centos/7/updates/x86_64/Packages/vim-enhanced-7.4.629-8.el7_9.x86_64.rpm http://mirrors.cloud.aliyuncs.com/centos/7/updates/x86_64/Packages/vim-common-7.4.629-8.el7_9.x86_64.rpm
下载软件包及其依赖的软件包到当前目录:
yumdownloader --resolve vim
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile --> Running transaction check ---> Package vim-enhanced.x86_64 2:7.4.629-8.el7_9 will be installed --> Processing Dependency: vim-common = 2:7.4.629-8.el7_9 for package: 2:vim-enhanced-7.4.629-8.el7_9.x86_64 --> Running transaction check ---> Package vim-common.x86_64 2:7.4.160-6.el7_6 will be updated --> Processing Dependency: vim-common = 2:7.4.160-6.el7_6 for package: 2:vim-enhanced-7.4.160-6.el7_6.x86_64 ---> Package vim-common.x86_64 2:7.4.629-8.el7_9 will be an update --> Running transaction check ---> Package vim-enhanced.x86_64 2:7.4.160-6.el7_6 will be updated --> Finished Dependency Resolution Delta RPMs disabled because /usr/bin/applydeltarpm not installed.
查看下载的软件包文件:
[root@cdgeekcamp ~]# ll vim* -rw-r--r-- 1 root root 6205700 Dec 18 04:37 vim-common-7.4.629-8.el7_9.x86_64.rpm -rw-r--r-- 1 root root 1106008 Dec 18 04:37 vim-enhanced-7.4.629-8.el7_9.x86_64.rpm
12.9. 仓库管理
12.9.1. 基础用法
yum repolist
yum-config-manager --add-repo 文件路径或网址
yum-config-manager --enable Yum仓库名称
yum-config-manager --disable Yum仓库名称
- 常用参数
add-repo |
从指定文件或网址增加Yum仓库(并启用) |
enable |
启用Yum仓库 |
disable |
禁用Yum仓库 |
12.9.2. 安装依赖软件
安装 yum-config-manager
工具:
yum install -y yum-utils
12.9.3. 列出Yum仓库
yum repolist
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile repo id repo name status base/7/x86_64 CentOS-7 10,072 epel/x86_64 Extra Packages for Enterprise Linux 7 - x86_64 13,592 extras/7/x86_64 CentOS-7 476 updates/7/x86_64 CentOS-7 2,189 repolist: 26,329
12.9.4. 增加并启用Yum仓库
创建临时文件 "~/nginx.repo"
:
cat << EOF > ~/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF
增加并启用Yum仓库:
yum-config-manager --add-repo ~/nginx.repo
Loaded plugins: fastestmirror adding repo from: /root/nginx.repo grabbing file /root/nginx.repo to /etc/yum.repos.d/nginx.repo repo saved to /etc/yum.repos.d/nginx.repo
确认nginx仓库已经启用:
yum repolist
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile repo id repo name status base/7/x86_64 CentOS-7 10,072 epel/x86_64 Extra Packages for Enterprise Linux 7 - x86_64 13,592 extras/7/x86_64 CentOS-7 476 nginx-stable/7/x86_64 nginx stable repo 224 updates/7/x86_64 CentOS-7 2,189 repolist: 26,553
出现 "nginx-stable"
,表示nginx仓库已经启用。
12.9.5. 禁用Yum仓库
yum-config-manager --disable nginx-stable
Loaded plugins: fastestmirror ============================= repo: nginx-stable ============================= [nginx-stable] ......(省略部分内容)...... enabled = 0 ......(省略部分内容)......
yum repolist 命令可以帮助确认仓库状态。禁用nginx仓库后,命令结果不会有 nginx-stable 字样。
|
12.9.6. 启用Yum仓库
yum-config-manager --enable nginx-stable
Loaded plugins: fastestmirror ============================= repo: nginx-stable ============================= [nginx-stable] ......(省略部分内容)...... enabled = 1 ......(省略部分内容)......
12.10. 搜索
"search"
选项可以搜索软件包的名称、描述或简介中的文字。
12.10.1. 基础用法
yum search 关键字
12.10.2. 搜索nginx相关的软件包
yum search curl
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile ======================================== N/S matched: nginx ======================================= collectd-curl.x86_64 : Curl plugin for collectd collectd-curl_json.x86_64 : Curl JSON plugin for collectd collectd-curl_xml.x86_64 : Curl XML plugin for collectd curlftpfs.x86_64 : CurlFtpFS is a filesystem for accessing FTP hosts based on FUSE and libcurl flickcurl-devel.x86_64 : Development files for flickcurl libcurl-devel.x86_64 : Files needed for building applications with libcurl libcurl-devel.i686 : Files needed for building applications with libcurl nbdkit-plugin-curl.x86_64 : HTTP/FTP/SSH (cURL) plugin for nbdkit ocaml-curl.x86_64 : OCaml Curl library (ocurl) ocaml-curl-devel.x86_64 : Development files for ocaml-curl perl-WWW-Curl.x86_64 : Perl extension interface for libcurl php-pear-Net-Curl.noarch : OO interface to PHP's cURL extension python-pycurl.x86_64 : A Python interface to libcurl python34-pycurl.x86_64 : Python interface to libcurl for Python 3 python36-pycurl.x86_64 : Python interface to libcurl for Python 3 uwsgi-alarm-curl.x86_64 : uWSGI - Curl alarm plugin uwsgi-plugin-curl-cron.x86_64 : uWSGI - Plugin for CURL Cron support curl.x86_64 : A utility for getting files from remote servers (FTP, HTTP, and others) flickcurl.x86_64 : C library for the Flickr API libcurl.x86_64 : A library for getting files from web servers libcurl.i686 : A library for getting files from web servers python2-httpie.noarch : A Curl-like tool for humans rubygem-curb.x86_64 : Ruby libcurl bindings uget.x86_64 : Download manager using GTK+ and libcurl uwsgi-alarm-xmpp.x86_64 : uWSGI - Curl alarm plugin Name and summary matches only, use "search all" for everything.
"search all" 使用频率极低。
|
curl
和 libcurl-devel
是我要找的软件包名称,安装之:
yum install -y curl libcurl-devel
你找到想要的软件包了吗?
12.11. 文件属于哪个软件包
知道某个文件的名称,但不清楚具体的软件包名称时,"provides"
选项很管用。
找到软件包名称后,直接 "yum install -y 软件包名称"
搞定!
12.11.1. 基础用法
yum provides 文件绝对路径或星号表达式
12.11.2. 不知道 "curl.h"
的绝对路径时
yum provides */curl.h
"*/curl.h" 开头的星号不能少。
|
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile libcurl-devel-7.29.0-59.el7.i686 : Files needed for building applications with libcurl Repo : base Matched from: Filename : /usr/include/curl/curl.h libcurl-devel-7.29.0-59.el7.x86_64 : Files needed for building applications with libcurl Repo : base Matched from: Filename : /usr/include/curl/curl.h ......
从结果看,只有软件包 "libcurl-devel"
包含 "*/curl.h"
,文件绝对路径:"/usr/include/curl/curl.h"
。
要不要试试 yum provides /curl. ?
|
12.11.3. 知道 "curl.h"
的绝对路径时
yum provides /usr/include/curl/curl.h
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile libcurl-devel-7.29.0-59.el7.i686 : Files needed for building applications with libcurl Repo : base Matched from: Filename : /usr/include/curl/curl.h libcurl-devel-7.29.0-59.el7.x86_64 : Files needed for building applications with libcurl Repo : base Matched from: Filename : /usr/include/curl/curl.h ......
12.12. 加速网络访问
12.12.1. 用国内镜像服务器加速
备份配置文件:
cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
使用阿里云镜像服务器:
new_mirror_url=http://mirrors.aliyun.com/
cat << EOF > /etc/yum.repos.d/CentOS-Base.repo
[base]
name=CentOS-\$releasever
enabled=1
failovermethod=priority
baseurl=${new_mirror_url}centos/\$releasever/os/\$basearch/
gpgcheck=1
gpgkey=${new_mirror_url}centos/RPM-GPG-KEY-CentOS-7
[updates]
name=CentOS-\$releasever
enabled=1
failovermethod=priority
baseurl=${new_mirror_url}centos/\$releasever/updates/\$basearch/
gpgcheck=1
gpgkey=${new_mirror_url}centos/RPM-GPG-KEY-CentOS-7
[extras]
name=CentOS-\$releasever
enabled=1
failovermethod=priority
baseurl=${new_mirror_url}centos/\$releasever/extras/\$basearch/
gpgcheck=1
gpgkey=${new_mirror_url}centos/RPM-GPG-KEY-CentOS-7
EOF
还可以用网易的镜像服务器:
new_mirror_url=http://mirrors.163.com/
cat << EOF > /etc/yum.repos.d/CentOS-Base.repo
[base]
name=CentOS-\$releasever
enabled=1
failovermethod=priority
baseurl=${new_mirror_url}centos/\$releasever/os/\$basearch/
gpgcheck=1
gpgkey=${new_mirror_url}centos/RPM-GPG-KEY-CentOS-7
[updates]
name=CentOS-\$releasever
enabled=1
failovermethod=priority
baseurl=${new_mirror_url}centos/\$releasever/updates/\$basearch/
gpgcheck=1
gpgkey=${new_mirror_url}centos/RPM-GPG-KEY-CentOS-7
[extras]
name=CentOS-\$releasever
enabled=1
failovermethod=priority
baseurl=${new_mirror_url}centos/\$releasever/extras/\$basearch/
gpgcheck=1
gpgkey=${new_mirror_url}centos/RPM-GPG-KEY-CentOS-7
EOF
12.12.2. 缓存仓库软件数据
yum的所有操作都会访问网络仓库服务器,makecache
后会减少多数网络请求,加速操作。
yum clean all
yum makecache
Loaded plugins: fastestmirror Determining fastest mirrors base | 3.6 kB 00:00 epel | 4.7 kB 00:00 extras | 2.9 kB 00:00 updates | 2.9 kB 00:00 (1/17): base/7/x86_64/group_gz | 153 kB 00:00 (2/17): base/7/x86_64/primary_db | 6.1 MB 00:00 (3/17): base/7/x86_64/other_db | 2.6 MB 00:00 (4/17): base/7/x86_64/filelists_db | 7.2 MB 00:00 (5/17): epel/x86_64/group_gz | 96 kB 00:00 (6/17): epel/x86_64/updateinfo | 1.0 MB 00:00 (7/17): epel/x86_64/prestodelta | 692 B 00:00 (8/17): epel/x86_64/filelists_db | 12 MB 00:00 (9/17): epel/x86_64/primary_db | 6.9 MB 00:00 (10/17): epel/x86_64/other_db | 3.4 MB 00:00 (11/17): extras/7/x86_64/primary_db | 236 kB 00:00 (12/17): extras/7/x86_64/filelists_db | 231 kB 00:00 (13/17): extras/7/x86_64/other_db | 139 kB 00:00 (14/17): nginx-stable/7/x86_64/primary_db | 63 kB 00:00 (15/17): updates/7/x86_64/filelists_db | 4.7 MB 00:00 (16/17): updates/7/x86_64/primary_db | 8.0 MB 00:00 (17/17): updates/7/x86_64/other_db | 610 kB 00:00 Metadata Cache Created
12.13. EPEL扩展仓库
EPEL是官方维护的扩展仓库,包含很多实用的软件包。
12.13.1. 安装EPEL
yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
12.13.2. 用国内EPEL镜像服务器加速
由于官方服务器在国内速度慢,建议使用国内EPEL镜像服务器。此处以阿里云为例:
new_mirror_url=https://mirrors.aliyun.com/ cp /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.bak sed -i "s|#baseurl=http://download.fedoraproject.org/pub/|baseurl=${new_mirror_url}|g" /etc/yum.repos.d/epel.repo
还可以替换成清华大学的服务器: "https://mirrors.tuna.tsinghua.edu.cn/"
12.13.3. 缓存仓库软件数据
设置完毕后,更新仓库缓存:
yum clean all
yum makecache
13. 服务管理
13.1. 简介
CentOS 7依靠Systemd管理各种系统服务,service start 服务名称
这种方式已经被过时,systemctl start 服务名称
才是首选。
Systemd是Linux的系统和服务管理器。提供许多特性,例如开机时并行启动服务(完美发挥SSD硬盘性能优势,不再等待排队启动服务)、按需启动服务、服务启动顺序(依赖关系)控制等。
13.1.1. 服务管理的基本逻辑
安装某个软件及其附带的服务后,设置为开机启动,大概要经过以下几个步骤:
-
安装(复制)服务文件(
"UNIT FILE"
)到 systemd 指定目录; -
设置服务状态(
"STATE"
)为"enabled"
,每次开机后服务会自动启动; -
在当前系统状态下(无需重启),启动服务;
13.1.2. 一些准备工作
我们以Nginx为例,演示服务管理操作。
安装Nginx:
yum install -y nginx
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile base | 3.6 kB 00:00:00 epel | 4.7 kB 00:00:00 extras | 2.9 kB 00:00:00 nginx-stable | 2.9 kB 00:00:00 updates | 2.9 kB 00:00:00 (1/2): epel/x86_64/updateinfo | 1.0 MB 00:00:00 (2/2): epel/x86_64/primary_db | 6.9 MB 00:00:00 Resolving Dependencies --> Running transaction check ---> Package nginx.x86_64 1:1.16.0-1.el7.ngx will be updated ---> Package nginx.x86_64 1:1.20.0-1.el7.ngx will be an update --> Finished Dependency Resolution Dependencies Resolved ============================================================================================== Package Arch Version Repository Size ============================================================================================== Updating: nginx x86_64 1:1.20.0-1.el7.ngx nginx-stable 790 k Transaction Summary ============================================================================================== Upgrade 1 Package Total size: 790 k Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Updating : 1:nginx-1.20.0-1.el7.ngx.x86_64 1/2 warning: /etc/nginx/conf.d/default.conf created as /etc/nginx/conf.d/default.conf.rpmnew warning: /etc/nginx/nginx.conf created as /etc/nginx/nginx.conf.rpmnew Cleanup : 1:nginx-1.16.0-1.el7.ngx.x86_64 2/2 Verifying : 1:nginx-1.20.0-1.el7.ngx.x86_64 1/2 Verifying : 1:nginx-1.16.0-1.el7.ngx.x86_64 2/2 Updated: nginx.x86_64 1:1.20.0-1.el7.ngx Complete!
13.2. 列表服务
13.2.1. 基础用法
systemctl list-unit-files
systemctl list-unit --all
systemctl --failed
列表时,内容超出屏幕,显示不完。按 Enter、↓ 或 PgDn 向下翻,按 Ctrl+C 或 q 退出。 |
13.2.2. 列出已安装的服务文件及其状态
systemctl list-unit-files
UNIT FILE STATE proc-sys-fs-binfmt_misc.automount static dev-hugepages.mount static dev-mqueue.mount static sys-kernel-debug.mount static tmp.mount disabled brandbot.path disabled systemd-ask-password-console.path static systemd-ask-password-plymouth.path static systemd-ask-password-wall.path static session-482.scope static aliyun.service disabled arp-ethers.service disabled atd.service enabled auditd.service enabled autovt@.service enabled ..... systemd-readahead-done.timer indirect systemd-tmpfiles-clean.timer static 254 unit files listed.
13.2.3. 列出已加载的服务
systemctl list-units
-.mount loaded active mounted / dev-hugepages.mount loaded active mounted Huge Pages File System dev-mqueue.mount loaded active mounted POSIX Message Queue File System run-user-0.mount loaded active mounted /run/user/0 sys-kernel-config.mount loaded active mounted Configuration File System sys-kernel-debug.mount loaded active mounted Debug File System systemd-ask-password-plymouth.path loaded active waiting Forward Password Requests to Plym systemd-ask-password-wall.path loaded active waiting Forward Password Requests to Wall session-482.scope loaded active running Session 482 of user root aegis.service loaded active exited LSB: aegis update. atd.service loaded active running Job spooling tools auditd.service loaded active running Security Auditing Service chronyd.service loaded active running NTP client/server mysqld.service loaded active running MySQL Server network.service loaded active running LSB: Bring up/down networking nginx.service loaded active running nginx - high performance web serve ..... LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type. 95 loaded units listed. Pass --all to see loaded but inactive units, too. To show all installed unit files use 'systemctl list-unit-files'.
13.2.4. 列出所有服务
systemctl list-units --all
UNIT LOAD ACTIVE SUB DESCRIPTION dev-ttyS0.device loaded active plugged /dev/ttyS0 dev-ttyS1.device loaded active plugged /dev/ttyS1 dev-ttyS2.device loaded active plugged /dev/ttyS2 dev-ttyS3.device loaded active plugged /dev/ttyS3 dev-vda.device loaded active plugged /dev/vda dev-vda1.device loaded active plugged /dev/vda1 ...... time-sync.target loaded inactive dead System Time Synchronized timers.target loaded active active Timers umount.target loaded inactive dead Unmount All Filesystems letsencrypt.timer loaded active waiting Monthly renewal of Let's Encry systemd-readahead-done.timer loaded inactive dead Stop Read-Ahead Data Collectio systemd-tmpfiles-clean.timer loaded active waiting Daily Cleanup of Temporary Dir LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type. 181 loaded units listed. To show all installed unit files use 'systemctl list-unit-files'.
13.2.5. 列出失败状态的服务
systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION ● cloud-init-local.service loaded failed failed Initial cloud-init job (pre-networking) ● cloud-init.service loaded failed failed Initial cloud-init job (metadata service crawl ● letsencrypt.service loaded failed failed Let's Encrypt renewal ● postfix.service loaded failed failed Postfix Mail Transport Agent LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type. 4 loaded units listed. Pass --all to see loaded but inactive units, too. To show all installed unit files use 'systemctl list-unit-files'.
13.3. 查找服务
13.3.1. 基础用法
systemctl list-unit 星号匹配表达式
systemctl list-unit --all 星号匹配表达式
13.3.2. 列出指定名称的服务文件及其状态
列出名称包含 "nginx"
字样的服务:
systemctl list-unit-files *nginx*
UNIT FILE STATE nginx-debug.service disabled nginx.service enabled 2 unit files listed.
13.3.3. 列出指定名称的服务
列出名称包含 "nginx"
字样的服务:
systemctl list-units -all *nginx*
UNIT LOAD ACTIVE SUB DESCRIPTION nginx.service loaded inactive dead nginx - high performance web server LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type. 1 loaded units listed. To show all installed unit files use 'systemctl list-unit-files'.
13.4. 启动服务
13.4.1. 基础用法
systemctl start 服务名称
13.4.2. 启动Nginx服务
systemctl start nginx
如果启动或重启服务时,屏幕上出现类似提示: Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details. 说明服务操作失败,通过查看服务状态( |
13.5. 状态检查
13.5.1. 基础用法
systemctl status 服务名称
13.5.2. 查看Nginx服务状态
systemctl status nginx
● nginx.service - nginx - high performance web server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled) Active: active (running) since Thu 2021-05-20 20:01:10 CST; 3 days ago Docs: http://nginx.org/en/docs/ Main PID: 7858 (nginx) CGroup: /system.slice/nginx.service ├─7858 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf └─7859 nginx: worker process May 20 20:01:09 cdgeekcamp systemd[1]: Starting nginx - high performance web server... May 20 20:01:10 cdgeekcamp systemd[1]: PID file /var/run/nginx.pid not readable (yet?) a...rt. May 20 20:01:10 cdgeekcamp systemd[1]: Started nginx - high performance web server. Hint: Some lines were ellipsized, use -l to show in full.
启动成功后,可以看到 "Active: active (running)"
字样。
如果启动服务时出现错误,会看到这样的内容:
● nginx.service - nginx - high performance web server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled) Active: failed (Result: exit-code) since Sun 2021-05-23 22:27:55 CST; 7min ago Docs: http://nginx.org/en/docs/ Process: 7945 ExecStop=/bin/sh -c /bin/kill -s TERM $(/bin/cat /var/run/nginx.pid) (code=exited, status=0/SUCCESS) Process: 7935 ExecReload=/bin/sh -c /bin/kill -s HUP $(/bin/cat /var/run/nginx.pid) (code=exited, status=0/SUCCESS) Process: 7949 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=1/FAILURE) Main PID: 7916 (code=exited, status=0/SUCCESS) May 23 22:27:55 cdgeekcamp systemd[1]: Stopped nginx - high performance web server. May 23 22:27:55 cdgeekcamp systemd[1]: Starting nginx - high performance web server... May 23 22:27:55 cdgeekcamp nginx[7949]: nginx: [emerg] unexpected ";" in /etc/nginx/ngin...:78 May 23 22:27:55 cdgeekcamp systemd[1]: nginx.service: control process exited, code=exite...s=1 May 23 22:27:55 cdgeekcamp systemd[1]: Failed to start nginx - high performance web server. May 23 22:27:55 cdgeekcamp systemd[1]: Unit nginx.service entered failed state. May 23 22:27:55 cdgeekcamp systemd[1]: nginx.service failed. Hint: Some lines were ellipsized, use -l to show in full.
"Active: failed (Result: exit-code) "
说明启动服务时有错误。
注意软件打印的提示:
May 23 22:27:55 cdgeekcamp nginx[7949]: nginx: [emerg] unexpected ";" in /etc/nginx/ngin...:78
通常解决软件(此处为Nginx)配置错误后,重启服务即可。
13.6. 重启服务
13.6.1. 基础用法
systemctl restart 服务名称
13.6.2. 重启Nginx服务
systemctl restart nginx
13.7. 停止服务
13.7.1. 基础用法
systemctl stop 服务名称
13.7.2. 停止Nginx服务
systemctl stop nginx
确认Nginx服务状态:
systemctl status nginx
● nginx.service - nginx - high performance web server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled) Active: inactive (dead) since Sun 2021-05-23 22:45:46 CST; 33s ago Docs: http://nginx.org/en/docs/ Process: 8003 ExecStop=/bin/sh -c /bin/kill -s TERM $(/bin/cat /var/run/nginx.pid) (code=exited, status=0/SUCCESS) Process: 7935 ExecReload=/bin/sh -c /bin/kill -s HUP $(/bin/cat /var/run/nginx.pid) (code=exited, status=0/SUCCESS) Process: 7993 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS) Main PID: 7994 (code=exited, status=0/SUCCESS) May 23 22:40:44 cdgeekcamp systemd[1]: Starting nginx - high performance web server... May 23 22:40:45 cdgeekcamp systemd[1]: PID file /var/run/nginx.pid not readable (yet?) a...rt. May 23 22:40:45 cdgeekcamp systemd[1]: Started nginx - high performance web server. May 23 22:45:46 cdgeekcamp systemd[1]: Stopping nginx - high performance web server... May 23 22:45:46 cdgeekcamp systemd[1]: Stopped nginx - high performance web server. Hint: Some lines were ellipsized, use -l to show in full.
"Active: inactive (dead) "
表示服务未启动。
13.8. 重载服务
13.8.1. 基础用法
systemctl reload 服务名称
13.8.2. 重载Nginx服务
systemctl reload nginx
13.9. 查看服务
13.9.1. 基础用法
systemctl cat 服务名称
13.9.2. 查看Nginx服务文件内容
systemctl cat nginx
# /usr/lib/systemd/system/nginx.service [Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/var/run/nginx.pid ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /var/run/nginx.pid)" ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /var/run/nginx.pid)" [Install] WantedBy=multi-user.target
13.10. 禁止开机启动
13.10.1. 基础用法
systemctl disable 服务名称
13.10.2. 禁止开机启动Nginx服务
systemctl disable nginx
Removed symlink /etc/systemd/system/multi-user.target.wants/nginx.service.
已经禁止开机启动的服务,重复执行 disable 操作,屏幕不会显示任何提示。
|
确认Nginx服务状态:
systemctl is-enabled nginx
disabled
systemctl mask nginx 可以直接禁止手动启动Nginx服务,反之则是 systemctl unmask nginx 。
|
13.11. 启用开机启动
13.11.1. 基础用法
systemctl disable 服务名称
13.11.2. 开机启动Nginx服务
systemctl enable nginx
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
已经禁止开机启动的服务,重复执行 enable 操作,屏幕不会显示任何提示。
|
确认Nginx服务状态:
systemctl is-enabled nginx
enabled
附录 A: 客户端工具之Linux终端
A.1. Linux终端安装
笔记本或PC上安装有任何Linux发行版(Ubuntu、Deepin Linux、Manjaro Linux、ArchLinux等),系统自带Linux终端,无需单独安装。
A.2. Linux终端连接远程主机
使用 ssh
命令登录远程主机非常简单。如远程主机地址为 192.168.2.236
,在终端输入以下命令:
ssh root@192.168.2.236
其中,
|
如果你是第一次使用 ssh
连接这台远程主机,你会看到像下面这样的提示消息:
先 yes
,后 Enter,继续连接
输入 root
用户密码,然后 Enter 。还是和设置密码时类似,密码不会显示在屏幕上
之前输入 Warning: Permanently added '192.168.2.236' (ECDSA) to the list of known hosts. 正常情况下,每台远程主机只有一个指纹。这样做是为了网络安全,防止中间人攻击。 |
密码校验成功,你得到了远程主机的交互式终端权限
看看远程主机空间使用情况
A.3. Linux设置无密码登录
密码不方便记忆,有时候为了安全设置长密码让问题更凸显,也有时候是因为远程主机太多。
我个人的习惯是第一次登录之后立刻设置无密码登录,业内大家更喜欢称为密钥登录。
如果你是第一次使用无密码登录,需要生成密钥对。密钥对生成后,可以重复使用,不需要每次生成。我的远程主机使用密钥对已经超过十年。
如果你有密钥对,直接上传公钥(锁)到远程主机,使用私钥(钥匙)可以登录远程主机。不用再生成密钥对。
在开始之前,需要说明一下。
密钥对包括两个文件:私钥文件(Private Key),公钥文件(Public Key)。
私钥文件 |
相当于门钥匙,作为登录远程主机的关键。 |
公钥文件 |
相当于门锁,只要有钥匙就可以打开。公钥文件可以发布到任何地方,不需要保密。 |
私钥文件不能外泄,否则远程主机有严重的安全风险。
不然,某天你可能收到勒索邮件,对方要求支付10个比特币,否则删除数据库。
A.3.1. 生成密钥对
生成不带密码的密钥对: ssh-keygen -N "" -f ~/.ssh/mk
~/.ssh/mk 只是密钥对文件名前缀,可以随意更换。比如,~/.ssh/prolinux
|
如下图所示,会生成两个文件:
-
私钥文件:
~/.ssh/mk
-
公钥文件:
~/.ssh/mk.pub
A.3.2. 上传公钥文件到远程主机
OK,按照上面的命令,你得到了公钥文件 ~/.ssh/mk.pub
。
接下来,将公钥文件上传到 192.168.2.236
(安装一把远程主机的“锁”)。
然后,你才能用私钥(钥匙)登录远程主机。
步骤如下:
-
首先,执行命令:
ssh-copy-id -i ~/.ssh/mk.pub root@192.168.2.236
-
输入远程主机密码
在输入密码时,屏幕上是看不见密码的 |
-
密码检验成功,你会看到与以下图片类似的结果
至此,就给远程主机安装上了一把“锁”。
A.3.3. 在本地Linux终端中配置私钥
我们搞定“锁”之后,在本地Linux终端中配置“钥匙”。
多远程主机使用相同私钥
你可以增加 IdentityFile ~/.ssh/mk
一行到配置文件中。这样的话,可以使用 ~/.ssh/mk
登录所有远程主机。
echo "IdentityFile ~/.ssh/mk" >> ~/.ssh/config
远程主机使用指定私钥
Host
参数也支持较复杂的私钥设置。
语法如下:
Host 192.168.2.236 IdentityFile ~/.ssh/mk
还不会在Linux下编辑文件?
你可以一句话增加设置到文件:
cat << EOF >> ~/.ssh/config
Host 192.168.2.236
IdentityFile ~/.ssh/mk
EOF
执行这个命令时,必须按两次 Enter。 |
Host
后面的IP地址表示登录远程主机:192.168.2.236
时,使用私钥 ~/.ssh/mk
你猜得没错,
|
A.3.4. 测试无密码登录
远程主机已经装上锁,也创建了本地配置文件。现在可以测试下:
ssh root@192.168.2.236
无密码登录远程主机成功。
exit
可以注销(退出登录)。我推荐按 Ctrl+D 退出,更方便。
A.3.5. Troubleshooting
保证以下关键点正确无误,就可以100%配置成功。
客户端:“~/.ssh/”文件夹
-
~/.ssh/
文件夹只能被当前用户写入,也就是下图标记的drwxr-xr-x
中第一个w
必须存在。
修复方法: chmod 700 ~/.ssh/
客户端:“~/.ssh/mk”私钥文件
-
~/.ssh/mk
文件权限必须是600
,也就是标记的这样-rw-------
修复方法: chmod 600 ~/.ssh/mk
文件权限错误时,私钥无法登录并报错
服务端(192.168.2.236):“~/.ssh/”文件夹
-
~/.ssh/
文件夹只能被当前用户写入,也就是下图标记的drwx------
中第一个w
必须存在。
修复方法: chmod 755 ~/.ssh/
服务端(192.168.2.236):“~/.ssh/authorized_keys”文件
-
~/.ssh/authorized_keys
文件同样只能被当前用户写入,权限可以是400
(-r-------
)或者600
(-rw-------
)。
修复方法: chmod 600 ~/.ssh/authorized_keys
使用 ssh-copy-id 上传公钥,权限必须是 600 ( -rw------- )。
|
如下图所示:
-
~/.ssh/authorized_keys
中每一行都是一把“锁”(公钥),对应一把“钥匙”(私钥)。也就是说,可以多人同时使用相同用户名但不同私钥登录远程主机。
查看ssh命令日志
查看日志是诊断连接问题最重要的手段。
第一种是远程主机系统的登录日志文件,另一种是执行 ssh
命令时打印出来的调试信息。
这里以后者为例:ssh root@192.168.2.236 -v
可以看到截图中有以下信息:
debug1: Trying private key: /home/mk/.ssh/mk debug1: Authentication succeeded (publickey).
这意味着,我们配置的 config
文件生效了。
如果这个地方没有你配置的私钥文件,请检查 ~/.ssh/config
文件配置
附录 B: 传输文件之Linux终端
B.1. Linux终端
跟着下面的例子练习,只用三分钟搞定 scp
命令传输文件。
按照本书惯例,
本地 是指当前的操作界面,可以是 电脑、手机、其它远程主机。比如,我操作的 mk@archlinux
终端。
远程主机 是指服务器用途的系统,可以是物理裸机、云服务器、虚拟机。比如,第一章安装的虚拟机(192.168.2.236)。
B.1.1. 准备文件
-
在终端中创建目录,名称为
"ProLinux"
:
mkdir ProLinux
-
在目录
"ProLinux"
下创建名为"foo.txt"
的文件,文件内容为"test text: foo"
:
echo 'test text: foo' > ProLinux/foo.txt
-
同样的方式创建
"bar.txt"
echo 'test text: bar' > ProLinux/bar.txt
-
查看目录
"ProLinux"
下的文件,确认是否创建成功:
ls -l ProLinux/
[mk@archlinux ~]$ ls -l ProLinux/ 总用量 8 -rw-r--r-- 1 mk mk 15 2月 26 15:06 bar.txt -rw-r--r-- 1 mk mk 15 2月 26 15:06 foo.txt
B.1.2. 本地到远程主机
从本地上传目录到远程主机
-
上传整个
"ProLinux"
目录到远程主机"192.168.2.236"
上,登录用户名为"root"
,保存路径为root用户的家目录"~"
(/root
目录):
scp -r ProLinux/ root@192.168.2.236:~
[mk@archlinux ~]$ scp -r ProLinux/ root@192.168.2.236:~ bar.txt 100% 15 6.0KB/s 00:00 foo.txt 100% 15 26.4KB/s 00:00
从本地上传文件到远程主机
-
上传指定文件:
scp ProLinux/bar.txt root@192.168.2.236:~/ProLinux/
[mk@archlinux ~]$ scp ProLinux/bar.txt root@192.168.2.236:~/ProLinux/ bar.txt 100% 15 6.2KB/s 00:00
-
上传多个文件:
scp ProLinux/foo.txt ProLinux/bar.txt root@192.168.2.236:~/ProLinux/
[mk@archlinux ~]$ scp ProLinux/foo.txt ProLinux/bar.txt root@192.168.2.236:~/ProLinux/ foo.txt 100% 15 5.6KB/s 00:00 bar.txt 100% 15 34.8KB/s 00:00
-
可以使用星号
*
模糊匹配文件名,上传"ProLinux"
目录下所有文件:
scp ProLinux/* root@192.168.2.236:~/ProLinux/
[mk@archlinux ~]$ scp ProLinux/* root@192.168.2.236:~/ProLinux/ bar.txt 100% 15 5.3KB/s 00:00 foo.txt 100% 15 28.2KB/s 00:00
确认上传
-
登录远程主机:
ssh root@192.168.2.236
-
查看
"ProLinux"
目录:
ls -l ~
[root@prolinux ~]# ls -l ~ total 0 drwxr-xr-x. 2 root root 36 Feb 26 15:10 ProLinux
-
查看
"ProLinux"
目录下的文件:
ls -l ~/ProLinux
[root@prolinux ~]# ls -l ~/ProLinux total 8 -rw-r--r--. 1 root root 15 Feb 26 15:12 bar.txt -rw-r--r--. 1 root root 15 Feb 26 15:12 foo.txt
B.1.3. 从远程主机下载文件到本地
方法简单,交换 scp
命令中间的两部分。
-
从远程主机下载
"~/ProLinux"
目录:
scp -r root@192.168.2.236:~/ProLinux/ ~/
[mk@archlinux ~]$ scp -r root@192.168.2.236:~/ProLinux/ ~/ bar.txt 100% 15 8.7KB/s 00:00 foo.txt 100% 15 38.7KB/s 00:00
-
从远程主机下载
"foo.txt"
到本地:
scp root@192.168.2.236:~/ProLinux/foo.txt ~/ProLinux
[mk@archlinux ~]$ scp root@192.168.2.236:~/ProLinux/foo.txt ~/ProLinux foo.txt 100% 15 47.2KB/s 00:00
附录 C: egrep正则表达式扩展
C.1. 字符分类
根据习惯,可以将常见字符按范围分为:
- 大写字母
-
A、B、C、D、E、F、G、H、I、J、K、L、M、N、O、P、Q、R、S、T、U、V、W、X、Y、Z
- 小写字母
-
a、b、c、d、e、f、g、h、i、j、k、l、m、n、o、p、q、r、s、t、u、v、w、x、y、z
- 数字
-
0、1、2、3、4、5、6、7、8、9
- 空格
-
Space
- 制表符
-
Tab
- 英文标点符号
-
`、-、=、~、!、@、#、$、%、^、&、*、(、)、_、+、[、]、/、{、}、|、;、'、:、"、,、.、/、<、>、?
标准的正则表达式规范中,可以用 [A-Za-z] 这样的范围表达式来表示26个大写字母和26个小写字母。
C.2. 范围表达式
grep
使用特殊的范围表达式 [[:分类名称:]] 达到同样的效果。
具体的对照表如下:
分类名称 | 说明 | 示例 |
---|---|---|
[:lower:] |
26小写字母,相当于 [a-z]。 |
|
[:upper:] |
26大写字母,相当于 [A-Z]。 |
|
[:digit:] |
阿拉伯数字,相当于 [0-9]。 |
|
[:alpha:] |
大小写字母,[:lower:] 和 [:upper:] 的简写,相当于 [A-Za-z]。 |
|
[:alnum:] |
大小写字母和阿拉伯数字,[:alpha:] 和 [:digit:] 的简写,相当于 [0-9A-Za-z]。 |
|
[:space:] |
空格(Space)。 |
|
[:blank:] |
空格(Space)和制表符号(Tab)。 |
|
[:punct:] |
英文标点符号,包括:
|
|
[:cntrl:] |
(不可见的)控制符,包含ASCII编码中0~31(Null char~Unit Separator)、127(Delete)。 |
|
[:graph:] |
可见字符,[:alnum:] 和 [:punct:] 的简写。 |
|
[:print:] |
可打印的字符,[:alnum:]、[:punct:] 和 [:space:] 的简写。 |
|
[:xdigit:] |
十六进制数字:
相当于 [0-9A-Fa-f]。 |
|
当然,egrep
也支持取反操作符(^)。如:
egrep '[^[:digit:]]' ~/access.log
匹配不含数字的行,等同匹配包含大小写字母或英文标点符号的行。
foo.org 80 118.118.47.239 [18/Jan/2021:01:00:23] "GET /360.html HTTP/1.1" 200 bar.org 8080 115.202.80.105 [19/Feb/2021:02:12:24] "POST /login HTTP/1.1" 404 qux.com 80 123.6.49.36 [20/Mar/2021:03:22:24] "GET / HTTP/1.1" 200 quux.com 80 180.101.214.20 [21/Apr/2021:04:15:24] "GET /main.html HTTP/1.1" 200 quz.io 8080 180.101.52.35 [21/Aug/2021:13:18:24] "GET /log.jpg HTTP/1.1" 200 quuz.cn 8080 180.101.52.35 [21/Aug/2021:13:18:24] "GET /jquery.min.js HTTP/1.1" 403 quuuz.cn 8080 125.64.14.56 [21/Aug/2021:13:18:24] "GET /load.js HTTP/1.1" 200 corge.com 80 148.72.153.60 [22/May/2021:23:25:16] "GET /7.html HTTP/1.1" 500 garply.net 80 123.178.50.195 [23/Oct/2021:23:50:16] "POST /article/ HTTP/1.1" 301 garply.net 80 123.178.50.195 [23/Oct/2021:23:50:16] "POST /article_new/ HTTP/1.1" 200
以上每行都包含了字母,所以测试结果是正确的。