Linux 是一种开放源码 (open-source) 的类 UNIX 作业系统。虽然原先 Linux 只是由 Linus Torvalds 出于个人爱好而编写,但目前,Linux 已逐渐成为人们生活中不可或缺的一部分。从嵌入式设备到超级计算机,各处都有 Linux 的身影,在移动设备上广泛使用的 Android 系统正是建立在 Linux 内核之上。得益于其优雅的权限控制及优美的学习曲线,越来越多的服务器使用 Linux 以部署服务。
通常,我们安装使用的 Linux 是指经打包后的 Linux 发行版,其中包括 Debian(包括衍生版本 Ubuntu、Linux Mint)、Fedora(包括相关版本 Red Hat Enterprise Linux、CentOS)、openSUSE、Arch Linux(包括衍生版本 Manjaro)、Gentoo,不一而足。目前,Linux 发行版基本配备了各自的图形界面,使用与 Windows 系统相仿,容易入门。
但在一些服务器系统上,如 Ubuntu Server、CentOS 等,安装图形界面(GUI)导致系统正常运行的性能需求飙升,因此通常服务器仅安装命令行界面(CLI)。同时,即使在带有图形界面的 Linux 发行版,也
本文希望使用
写在前面
本教程遵守署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议,您可以自由地共享、演绎,但需遵守署名、非商业使用、相同方式共享条件,并且保证没有附加限制。更详细的说明可参见关于页面。
教程中提到的部分内容可能因为更新而不再适用,请您自行检查位于文章尾部的教程最后更新时间加以判断。如果教程内有过时内容,欢迎在评论中指出,作者会
学习本教程的前提是有一台可以正常工作的 Linux 计算机。虽然安装 Linux 系统并不是一件困难的事情,但却是一件复杂的事情,Linux 的发行版数量众多,安装过程并不能很容易地归纳为几个简单的步骤,因此本教程 Ubuntu Server 22.04 LTS
的安装过程。
本教程中涉及的命令较多且很常用,推荐大家在阅读时能 COPY
按钮,可以复制,粘贴后运行,查看结果。
样式说明
本教程正文部分以正常方式书写。
对于较为重要的附加说明或建议阅读的可选内容以
这是一个默认打开的折叠框(点击可以折叠)
里面是较为重要的附加说明,建议阅读。
对于非重要的附加说明或引申内容以
这是一个默认关闭的折叠框(点击可以展开)
里面是非重要的附加说明,或一些延伸,可以略过。
第〇章 什么是 Linux 命令
本章仅对 Linux 命令做一个初步的介绍,主要是给读者一个感性的认识,介绍一些命令的基本语法以及 Linux 自带的帮助文档如何查阅。如果读者暂时还不能连接上 Linux 终端,可以在大致浏览第〇章后,仔细阅读第一章的内容,确保连接上 Linux 终端后,再阅读第〇章的内容。第〇章的内容是 Linux 的
通常,第一次进入 Linux 命令行后,你可能会不知所措。因为你目力所及只有一个黑框框,里面有一些奇怪的英文字符,它通常是这样的:
1 | [xiao@server ~]$ |
其实,光标前面的这一串字符叫做 shell prompt
,中文可称为“命令行提示符”。默认状态下是 用户名@主机名
的格式,在上面例子中,用户名为 xiao
,主机名为 server
,后面跟的 ~
是命令行的当前目录,这将在后面介绍。美元符号($
)后面就是你的光标,你输入的字符将显示在后面。
试着输入 echo "Hello World"
然后回车,你会看到命令行输出了 Hello World
。
恭喜你运行了你的第一个 Linux 命令!
让我们乘胜追击,理解一下 Linux 命令的基本结构:
1 | [xiao@server ~]$ command [-options] [arguments] |
command
命令:表示命令的名称,例如ls
,chmod
,git
等等options
选项:表示命令的选项,中括号只是一个标记作用,表示这个选项是可选的,在实际书写时并不需要。通常,选项可以分为短选项与长选项。- 短选项:通常使用
-
引导,通常后面跟单个字符,例如-l
,-h
等。多个短选项可以直接组合,例如命令ls -l -h
可以直接表示为ls -lh
- 长选项:通常使用
--
引导,后面跟完整的单词,例如--human-readable
。例如上面的命令ls -lh
还可写成ls -l --human-readable
- 短选项:通常使用
arguments
参数:表示命令的作用对象,有些命令可能有多个参数,也可以没有参数
Linux 中命令、选项、参数之间使用空格来区分;
Linux 中命令严格区分大小写,对 Linux 而言 ls
与 LS
完全不同!
分析一下刚刚使用的命令 echo "Hello World"
的结构,echo
是这个命令(command)的名称,echo
有回声之意,所以其效果就是把参数字符串回显到命令行上;"Hello World"
就是命令的参数(arguments),在这里就是被回显的字符串。
如果要尝试一下选项(options)对命令的影响,试着输入 echo -n "Hello World"
,你大概会看到以下输出:
1 | [xiao@server ~]$ echo -n "Hello World" |
-n
选项的含义是不输出最后一个换行,所以你看到 Hello World
直接连在了 shell prompt
之后。
此后为了 shell prompt
,读者清楚即可。即不再使用:
1 | [xiao@server ~]$ echo -n "Hello World" |
转而使用:
1 | echo -n "Hello World" |
折行
在 Linux 如果输入命令很长,可以使用反斜杠 (\
) 折行,使指令续行,例如:
1 | echo "Hello world. \ |
其实等价于:
1 | echo "Hello world. I think that Xiao Space is a fascinating website. What you think?" |
显然,使用反斜杠折行后,代码的可读性更好了一些。一般来说,为了终端的兼容性,一行不应超过 79 个字符,如果多于 79 个字符,需要考虑折行,当然,这个规则也适用于其他编程语言。
需要注意反斜杠后必须立刻接换行符,否则可能会产生转义字符而失去续行效果。
帮助命令
如果在 Linux 中突然遇到有些记得名字的命令的选项或参数遗忘,可以查看 Linux 自带的帮助。通常,帮助命令可以归纳为 whatis
, --help
, man
, info
。
whatis
命令
whatis
会显示命令简短的功能描述,命令语法:
1 | whatis command |
例如:
1 | whatis echo |
--help
选项
在命令后加上 --help
通常可以显示使用方法和参数列表,有些时候,这个选项可以简写为 -h
,但要注意并不是所有命令都能如此简写,例如后面将要介绍的 ls -h
就是代表以人类可读的方式显示结果,这里 -h
是 --human-readable
的简写。因此,使用 --help
更具兼容性,命令语法:
1 | command --help |
例如:
1 | ls --help |
就会显示 ls
命令的帮助。
man
命令
man
命令可以查看命令描述或帮助手册(man 是 manual 的简称,是帮助文档的意思),命令语法:
1 | man [section] command |
例如:
1 | man echo |
就会进入 echo
命令的帮助手册。按 q 键可以退出。
如果出现 No manual entry for command (点击可以折叠)
通常情况,Linux 发行版会自带帮助手册。但对于一些精简的系统,可能并未安装 man
,如果出现此提示,可以学习本教程第四章如何在 Linux 上安装软件,然后安装 man-pages
包及 man-db
包。
关于 section 参数(点击可以展开)
在 man
命令的语法中,可以看到 section 参数,section 表示帮助手册的章节数,对应关系可以通过 man man-pages
查看
1 | MANUAL SECTIONS |
因为有些命令可能在不同的章节有重复,例如 printf
既在第 1 节,又在第 3 节,如果是要查看用户命令的 printf
,使用 man 1 printf
,如果是要查看 C 库中的 printf
,应使用 man 3 printf
。
info
命令
info
命令可以查看比 man
更详细的说明,命令语法:
1 | info command |
例如:
1 | info echo |
就会进入 echo
命令的说明,按 Q 键可以退出。
命令帮助的特殊符号 (点击可以折叠)
在查看命令帮助时,会出现 []
, <>
, |
等符号,它们的含义如下:[]
表示是可选的;<>
表示是可变化的;x|y|z
表示只能选择一个;-abc
表示三个参数(或任何二个)的混合使用
查看历史命令
在 Linux 下,我们有时希望知道最近执行的命令,history
会帮上大忙:
1 | history 5 # 显示最近使用的5个命令 |
在 Linux 下,我们有时还希望直接运行历史执行过的命令,!
会帮上大忙:
1 | !5 # 执行历史编号为 5 的命令,注意感叹号与数字间没有空格 |
一些便利的功能与快捷键
在 Linux 命令行中,你可能想中断一些耗时很长的命令的运行,亦或者是修改一些命令,或者是快速调出上一次的命令,实际上,这些操作都有快捷键可以完成,当然 Linux 命令行中的快捷键众多,这里只列出常用的部分。如对其他快捷键有兴趣,可以自行查阅 man bash
快捷键 CTRL + A:将光标移到行首
快捷键 CTRL + C:停止正在运行的任务
快捷键 CTRL + L:清屏
快捷键 TAB:命令补全
快捷键 ↑:历史命令,可以不断向上翻阅
小结
至此,恭喜你完成了第〇章的学习!第〇章主要带读者了解了 Linux 命令的基本结构、 Linux 的一些帮助命令及一些好用的快捷键。有了这些前置知识后,现在,让我们正式开始学习 Linux 吧!
第一章 连接到 Linux 终端
要想熟练使用 Linux 终端,头等要事当然是打开 Linux 终端。但可能,这件事可能有些时候并没有想象中那么容易。
图形界面 Linux 发行版
如果你在计算机上安装了带图形界面的 Linux 发行版,通常当你进入桌面系统后,可以在所有程序中找到“终端”软件,然后打开。
如果你使用 GNOME 或 KDE 桌面,你通常可以使用快捷键 CTRL + ALT + T 打开终端。这里的 T 是 Terminal(终端)的首字母。
不带图形界面的 Linux 发行版
如果你使用了不带图形界面的 Linux 发行版,那么你启动计算机后,就会自动进入终端,你只需输入账户名及密码即可。
远程连接上 Linux 终端
如果你的服务器安装了 Linux,但你希望通过远程方式访问,那么通常会使用 ssh
(Secure SHell, 安全外壳协议) 命令连接到 Linux 服务器。这时,服务端与客户端都需要进行一些配置。虽然配置 ssh 服务端(简称 sshd)很明显超出了本章的内容,但好在,通常 Linux 服务器版本都自带 sshd 服务,因此本章中我们默认认为其是开启的。即服务端的配置是完美的。
如果你一定要检查 ssh 服务端是否开启 (点击可以展开)
如果你想确认自己的 Linux 服务器是否开启了 ssh 服务,那么可以分为以下两种情况:
如果你的服务器是使用的 service 作为守护进程服务,那么可以运行以下命令:
1 | service sshd status |
如果看到 Active: active (running)
字样,说明 sshd 正在运行。
如果你的服务器使用 init.d
作为守护进程服务,那么可以运行以下命令:
1 | /etc/init.d/sshd status |
当然如果你不清楚具体的使用,你可以尝试运行上述两种命令,如果有一种提示正常,那么说明服务器已经开启了 ssh 服务。
如果你的 ssh 未做特殊配置,那通常开放在 22 端口,所以若你没有更改端口,你还可以通过以下命令检查:
1 | lsof -i :22 |
如果你没有安装 lsof
命令,那么可以使用相应的包管理器安装后再进行检查,具体可以参见第四章内容。
下面就要进行客户端的配置了,其实这一部分并不复杂,如果你的个人电脑就是 Linux 系统或是 macOS 系统,那么默认是安装了 ssh 客户端的,这里并不需要多做配置;如果你是 Windows 电脑,并且是 Windows 8 或更高的系统,那么 ssh 客户端也已经安装;如果是 Windows XP 或 Windows 7,那么需要自行安装 OpenSSH 程序。由于安装程序较为简单,因此这一部分不再赘述。下面分系统介绍如何打开客户端电脑的终端(命令提示符)。
Linux, macOS 系统打开终端
如果使用 Linux 或 macOS 系统,可以打开系统内置的终端(在 macOS 上,这通常被称为终端模拟器)。
Windows 系统打开命令提示符
在 Windows 系统下,你要先打开命令提示符(cmd)或 PowerShell 才能输入命令。
打开命令提示符,你可以使用 Win + R 快捷键打开运行,在里面输入 cmd
后回车(或点击确定),即可打开命令提示符。当然也可以使用 Windows 搜索,搜索命令提示符或 PowerShell 后打开。
运行 ssh
命令
打开终端后,可以输入以下命令:
1 | ssh username@IP [-p port] |
ssh 是命令的名称,username 是你想登录的远程账号的用户名,后面接 @
符号,然后紧跟远程主机的 IP 地址。如果你的服务器的 ssh 服务监听的端口不是 22 端口,那么可以使用 -p
选项指定端口,后面跟端口号即可。如果你不确定远程主机的 IP 地址,通常可以在远程主机上运行 ifconfig
命令查看,当然,对于初学者,往往直接询问网管或服务器相关人员更佳。
运行后,大概率会提示以下内容:
1 | The authenticity of host '192.168.1.100 (92.168.1.100)' cant be established. |
这是因为第一次连接到这个服务器,这个服务器的 IP 和对应的指纹还没有被客户端记录为可信的,所以弹出了一个警告,这时输入 yes
然后回车即可。当你同意后,你会发现提示了以下内容:
1 | Warning: Permanently added '192.168.1.100' (ECDSA) to the list of known hosts. |
这个警告提醒你已经将这个 IP 和对应的指纹加入了信任的列表,以后将不再提示。
恭喜你已经连接上终端了!
不输入密码连接 ssh(点击可以折叠)
当你使用 ssh 连接服务器时,每次都要输入密码,如果密码简单还好,但通常,服务器密码为了安全,都有大小写字母、数字、特殊字符构成,每次登录都要输入未免太过麻烦,那么,有没有一种方法可以不输入密码连接 ssh 呢?
当然有!而且还使用广泛!并且还更加安全!那就是使用密钥的方式登录。
密钥形式登录的原理是:利用密钥生成器制作一对密钥 —— 一只公钥和一只私钥。将公钥添加到服务器的某个账户上,然后在客户端利用私钥即可完成认证并登录。这样一来,没有私钥,任何人都无法通过 ssh 暴力破解你的密码来远程登录到系统。此外,如果将公钥复制到其他账户甚至主机,利用私钥也可以登录。
下面来讲解如何制作密钥对,将公钥添加给账户,设置 ssh,最后通过客户端登录。
如果你的客户端使用的是 Windows 系统,那么作者这里建议你安装 Git for Windows,这会为后面的安装带来很多的便利。你可以点击上面的连接,下载最新的 64 位版本,然后安装。Git 其实是一个非常好用的版本控制工具,作者也会在后面的章节进行介绍。在安装完成后,可以在开始菜单找到刚刚安装的 Git,并且会生成几个快捷方式,双击打开 Git Bash。如果你使用的是 Linux 系统或 macOS系统,直接打开终端即可。
为了与后面的 github 更好地兼容,我们运行以下命令生成一对密钥:
1 | ssh-keygen -t rsa -b 4096 -C "[email protected]" |
注意将 [email protected]
改为你的邮箱,如果你有 github 的账号,请改为你的 github 账号的注册邮箱。按回车后,会提示密钥的存储位置,这里保持默认即可。确认后,提示输入密钥的密码,通常情况下,这里可以留空,所以直接回车即可。按回车后,需要重复一遍密码,由于上次留空,这里再按一次回车即可。这样就生成好了公钥、私钥对。通常默认命名下,公钥是 id_rsa.pub
后缀是 public 的前三个字母,私钥是 id_rsa
无后缀。
私钥可以认为就是你的电脑的指纹,请务必妥善保存,否则别人就可以任意登录你的服务器,这是非常危险的!请注意,任何网站或服务器都不会索要你的私钥,因此请记住,私钥不上网!
第二步,就是在服务器上安装公钥。这一步只需运行命令:
1 | ssh-copy-id -i ~/.ssh/id_rsa.pub username@IP |
需要注意,要将 -i
选项后的路径替换为你的 id_rsa.pub
的路径,username 为服务器端的用户名,IP 为服务器的地址。实际上 ssh-copy-id
命令就是将公钥写入服务器的 ~/.ssh/authorized_key
文件中,只不过帮我们自动完成了上传公钥、写入文件、修改权限的操作。
最后,测试一下是否可以无密码登入:
1 | ssh username@IP |
如果你没有输入密码就已经登录了终端,恭喜你完成了无密码登录。实际上这一生成的密钥对中的公钥可以用于多个服务器,如果想要免密登陆第二台服务器时,只需要运行第二步即可。
终端与 shell 的争论(点击可以展开)
其实,在上面的叙述中,作者将终端与 shell 混为一谈,但严谨来看,它们是完全的不同的事物。通常意义下,可以认为终端负责输入命令,而 shell 负责解释命令并传递给内核。终端一词其实诞生在上世纪,诞生在那个计算机计算中心化,人们使用的通常是一套输入设备来操作计算机的时代(这套输入设备被称为终端)。因此,终端一词发展至今已然日渐式微,目前已经很难明晰终端与 shell 的界限。
当然,本文将终端与 shell 不做区分,并不是认为这两者区分并无必要,只是方便初学者的理解考量。因为初学者更在意与他交互的这个黑色窗口好不好用,而并不是这个窗口的名字到底是什么!
终端的介绍
通常情况下,当你使用 Linux 终端时,默认使用的 shell 是 bash(Bourne-Again SHell),它是 sh 的后继兼容版本。对初学者而言,这个 shell 功能已经足够强大。但如果你还有其他追求,例如代码补全、自动目录跳转等等,在后续使用中也可以使用其他 shell,例如 zsh、fish 等。需要注意的是,不同的 shell 的语法有微妙的区别,有时一种 shell 的脚本并不能在另一种 shell 中运行。本教程默认使用 bash 教学。
我不想在命令提示符中敲命令
如果你使用的是 Windows 系统,那你大概会觉得命令提示符实在是太丑陋了,实际上,正常的 Linux 使用者也不会将命令提示符作为自己的主要工作环境。目前已经有相当多好用、易用的终端工具,例如 PuTTY、MobaXterm 等等,这些工具或多或少方便了 Linux 终端使用,有些还自带了文件传输的功能,推荐初学者尝试。作者的工作流主要使用 Windows Terminal + Visual Studio Code 两款软件。限于篇幅,作者将自用的 Linux 环境搭建以及一些终端的美化技巧放在了 我的 Linux 深度学习工作环境丨环境搭建教程 中,欢迎读者查看。
至此,恭喜你完成了第一章的学习!第一章主要带读者了解了如何连接到 Linux 终端。并且还讲解了一些关于免密登录终端的技巧及一些关于终端的小知识。后者仅是一些拓展,并不需要完全掌握。阅读完本章后,你只需要连接上一个可以正常运行 Linux 命令的终端即可,不论这是本地的终端,还是通过 ssh 远程连接的终端,并不会影响后续章节的学习。
第二章 了解 Linux 文件操作
了解了 Linux 命令的基本结构并且连接上终端之后,我们就要正式开始学习 Linux 命令了。但是在学习之前,还请允许作者介绍一下 Linux 的文件系统,不同于 Windows 系统,Linux
Linux 文件系统
不同于 Windows 系统的盘符,Linux 系统只有一个根目录,不同的分区可以使用 /
表示。当你在终端中输入:ls /
后会看到以下输出:
1 | bin boot dev etc home lib lib32 lib64 libx32 lost+found media |
下面对其中的重要目录进行一些解释:
/bin
目录
bin 是 binaries (二进制文件) 的缩写,这个目录存放着最经常使用的命令。/boot
目录
这里存放的是启动 Linux 时使用的一些核心文件,包括一些连接文件以及镜像文件。/dev
目录
dev 是 device (设备) 的缩写,该目录下存放的是 Linux 的外部设备,在 Linux 中访问设备的方式和访问文件的方式是相同的。/etc
目录
etc 是 etcetera (等等) 的缩写,这个目录用来存放所有的系统管理所需要的配置文件 和子目录。/home
目录
用户的主目录 ,在 Linux 中,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的,例如,如果你的用户名是xiao
,那么你的主目录就是/home/xiao
。/lib
目录
lib 是 library (库) 的缩写,这个目录里存放着系统最基本的动态连接共享库,其作用类似于 Windows 里的 DLL 文件。几乎所有的应用程序都需要用到这些共享库。/lost+found
目录
这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件。/media
目录
Linux 系统会自动识别一些设备,例如U盘、光驱等等,当识别后,Linux 会把识别的设备挂载到这个目录下。/mnt
目录
mnt 是 mount (挂载) 的缩写,系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将光驱挂载在/mnt/
上,然后进入该目录就可以查看光驱里的内容了。/opt
目录
opt 是 optional (可选) 的缩写,这是给主机额外安装软件所摆放的目录。比如你安装一个ORACLE数据库则就可以放到这个目录下。默认是空的。/proc
目录
proc 是 processes (进程) 的缩写,/proc 是一种伪文件系统(也即虚拟文件系统),存储的是当前内核运行状态的一系列特殊文件,这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。/root
目录
该目录为系统管理员,也称作超级权限者的用户主目录。/sbin
目录
s 就是 super user 的意思,sbin 是 superuser binaries (超级用户的二进制文件) 的缩写,这里存放的是系统管理员使用的系统管理程序。/srv
目录
src 是 service (服务) 的缩写,该目录存放一些服务启动之后需要提取的数据。/sys
目录
sys 是 system (系统) 的缩写,具体的内容这里并不介绍。/tmp
目录
tmp 是 temporary (临时) 的缩写,这个目录是用来存放一些临时文件的。/usr
目录
usr 是 unix shared resources (共享资源) 的缩写,注意不是 user 的缩写,这是一个非常重要 的目录,用户的很多应用程序和文件都放在这个目录下,类似于 Windows 下的 Program Files 目录。/usr/bin
目录
系统用户使用的应用程序。/usr/sbin
目录
超级用户使用的比较高级的管理程序和系统守护程序。/usr/src
目录
src 是 source (源代码) 的缩写,该目录是内核源代码默认的放置目录。/var
目录
var 是 variable (变量) 的缩写,这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。/run
目录
是一个临时文件系统,存储系统启动以来的信息。当系统重启时,这个目录下的文件应该被删掉或清除。
在实际使用过程中,系统管理员操作最多的当属 /etc
, /usr
, /root
目录,普通用户访问最多的是自己的用户目录,即 /home/username
目录。
在 Linux 文件系统中,还有几个特殊的目录,一个是用户所在的工作目录(working directory),也被称为当前目录,可以使用一个点 .
表示。还有一个是当前目录的上一级目录,也称为父目录,可以使用两个点 ..
表示。还有一个是用户的用户目录,也被称为家目录,可以使用一个波浪号 ~
表示,对普通用户来说,就是代表 /home/username
目录,对超级用户来说,就是代表 /root
目录。
另外,如果一个目录或文件名以一个点 .
开始,表示这个目录或文件是一个隐藏目录或文件 (如:.bashrc)。即以默认方式查找时,不显示该目录或文件。
注意,如果你的 Linux 系统还有 /swap
目录,这说明你的系统启用了交换分区,交换分区是可以使用硬盘的一部分空间当作内容使用,对于小内存的机器非常有用,如果你的机器有很大的内存,也
使用命令创建交换文件并启用 (点击可以展开)
通常,这是系统管理员需要做的事情,这里做一些介绍,并不推荐初学者运行,除非你清楚每个命令的作用及后果。
1 | sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 # 创建一个 2GB 的位于根目录下的 |
如果你看到 Swap 一项增加了 2GB ,那么恭喜你已经开启交换文件成功了。但是现在每次启动后都要手动输入 swapon
命令才能开启,所以我们还需要写入开机启动项。
1 | echo "/swapfile swap swap defaults 0 0" >> /etc/fstab |
这样重启后,系统会自动挂载交换文件。当然,在实际使用中,你会发现内存占用少的时候,交换空间基本不起作用,如果你想在有充裕的内存的情况下也使用交换空间,可以使用以下命令查看交换空间的使用倾向:
1 | cat /proc/sys/vm/swappiness |
这个值越接近 100,意味着越偏向于使用交换空间而非物理内存,需要注意,将这个值增大会显著影响 Linux 系统的运行效率。你可以这样修改交换空间的偏好值:
1 | echo "vm.swappiness=90" >> /etc/sysctl.conf |
修改完成后重启即可看到更改。
Linux 的文件和目录严格区分大小写,./me/
和 ./Me/
是完全不同的两个目录,./me.py
与 ./Me.py
是完全不同的两个文件,这一点与 Windows 系统的默认行为大不相同,Windows 下目录和文件是不区分大小写的,这意味着同一文件夹下不可能同时出现 ./me.py
与 ./Me.py
文件,因为 Windows 认为这两个是同一个文件!请初学者务必注意其差别。
Linux 文件系统相关命令
在了解了 Linux 文件系统后,我们就可以正式开始 Linux 文件系统相关命令的学习了。Linux 中和文件操作相关的命令很多,这里只列举初学者最常用的一些命令,主要有 pwd
, cd
, ls
, cp
, mv
, touch
, rm
, mkdir
, rmdir
, cat
, head
, tail
, grep
, find
, zip
, tar
, nano
, vi
, ln
。
你很有可能会觉得这些命令都难以理解,但这是为了输入效率而做出的
另外,由于 Linux 中万物皆文件,其实上 FILE
指代。
目录相关
pwd
pwd 可以显示当前工作目录,是 Print Working Directory 的缩写。cd
cd 可以更改当前的工作目录,是 Change Directory 的缩写。
1 | cd [FILE] |
ls
ls 可以查看目录或文件信息,是 list 的缩写。
1 | ls [OPTION]... [FILE]... |
复制、移动、创建、删除文件或目录
cp
cp 可以复制文件或目录,是 copy 的缩写。
1 | cp [OPTION]... [-T] SOURCE DEST |
mv
mv 可以移动或重命名文件,是 move 的缩写。
1 | mv [OPTION]... [-T] SOURCE DEST |
touch
touch 可以创建一个空白文件,如果当前目录有同样的文件,则会更新文件的修改时间
1 | touch [OPTION]... FILE... |
rm
rm 可以删除文件或文件夹,是 remove 的缩写。
1 | rm [OPTION]... [FILE]... |
rm
命令是一个非常危险的命令,不像 Windows 系统,Linux 系统没有回收站,因此删除后就无法找回。因此,一般的 shell 会将 rm
作为 rm -i
的别名,具体的别名方式会在第三章介绍,这里只需要知道在 bash 中,rm
其实是 rm -i
,而 -i
选项会在每次移除时提示你,并要求你做确认。
!!!如果不是特殊需求,慎用 -f
选项强制删除!!!
mkdir
mkdir 可以创建一个文件夹,是 make directory 的缩写,有的 shell 还可以进一步简写为md
。
1 | mkdir [OPTION]... DIRECTORY... |
rmdir
rmdir 可以删除一个空文件夹,是 remove directory 的缩写,有的 shell 可以进一步简写为rd
。
1 | rmdir [OPTION]... DIRECTORY... |
rmdir
一般用于删除空文件夹,如果文件夹中有文件,建议使用 rm
命令。
查看文件
cat
cat 命令可以查看文件的内容,是 concatenate 的缩写。cat
命令常和输入输出重定向运算共同使用,以完成拼接文件等操作。
1 | cat [OPTION]... [FILE]... |
head
head 命令可以打印文件的开头几行
1 | head [OPTION]... [FILE]... |
tail
tail 命令可以打印文件的结尾几行
1 | tail [OPTION]... [FILE]... |
grep
grep 命令用于查找文件里符合条件的字符串,属于高级的 Linux 命令,这里仅作介绍,初学者用到的频率很少。find
find 命令用来在指定目录下查找文件,也是属于高级的 Linux 命令,这里仅作介绍,初学者用到的频率很少。
压缩与解压
在 Windows 上,我们经常会进行文件压缩、解压的操作,在 Linux 中,也有同样的操作。
zip
zip 是文件压缩命令,命令参数很多,这里只介绍常用的内容,如有需求,可以使用man zip
查看更多帮助。
1 | zip -r test.zip ./test # 压缩 test 文件夹生成 test.zip |
tar
tar 可以创建文件归档包,在 Linux 中非常常用,是 tape archive 的缩写。tar 的命令参数很多,这里只介绍常用的内容,如有需求,可以使用man tar
查看更多帮助。
1 | tar -czvf test.tar.gz ./test # 压缩 test 文件夹生成 test.tar.gz |
这里的选项较多,-c
表示 --create
即创建压缩文件;-z
表示 --gzip
即使用 gzip 压缩;-v
表示 --verbose
即显示命令的详细执行过程;-f
表示 --file
后面跟要创建的归档名,也就是压缩包名;-x
表示 --extract
即提取压缩文件。
当然,如果不使用 gzip 压缩,还可以使用以下的命令:
1 | tar -cvf test.tar ./test # 压缩 test 文件夹生成 test.tar |
文本编辑器
在 Linux 上,我们常常会有文本编辑的需求,通常,我们使用 nano
或 vi
进行文本编辑。
nano
nano 是一个字符终端的文本编辑器,它比 vi、vim 要简单得多,比较适合 Linux 初学者使用。
1 | nano test.txt # 编辑 test.txt |
进入 nano 编辑器后,你会在整个终端的下侧看见快捷键提示,使用其提示的快捷键即可完成文件编辑,保存的操作,其中,^X
表示 CTRL + X,M-U
表示 ALT + U,依此类推。
编辑完成后,使用 CTRL + O 写入所做的修改,这时 nano 会询问你写入文件的文件名,如果文件名不改变,直接回车即可,这样就可以保存文件,然后使用 CTRL + X 退出 nano。
vi
/vim
所有的 Unix Like 系统都会内置 vi 文书编辑器,其他的编辑器则不一定会存在。但是 vi 有一定的学习成本,目前使用更多的是vi
的改进版vim
。vim
具有程序编辑的能力,可以主动的以字体颜色辨别语法的正确性,方便程序设计。vim
的键盘图如下:
不要被这些花花绿绿的按键吓住,其实在实际使用中,常用的按键并不多,也很好记忆。如果你想学习 vim
的使用,可以在终端输入 vimtutor
,这时会有一个帮助教程教你使用 vim
。放心,这个教程非常简单!整个教程的时长大约 20 ~ 40 分钟,学习完成后,多使用几天 vim 就能熟练掌握,这会给编程效率带来很大的提升。如果你对作者使用的 vim
环境感兴趣,可以点击作者的另一篇文章 我的 Linux 深度学习工作环境丨环境搭建教程 查看。
由于 vim
非常常用,所以这里也大略介绍一下 vim
,旨在让初学者迅速了解如何编辑、保存一个文件,如果想进一步学习,最好还是跟随 vimtutor
学习。
vim 简要教程 (点击可以折叠)
基本上 vi/vim 共分为三种模式,分别是命令模式(Command mode),输入模式(Insert mode)和底线命令模式(Last line mode)。 这三种模式的作用分别是:
命令模式
用户刚刚启动 vi/vim,便进入了命令模式。此状态下敲击键盘动作会被Vim识别为命令,而非输入字符。比如我们此时按下 i
,并不会输入一个字符,i
被当作了一个命令。
以下是常用的几个命令:
i
切换到输入模式,以输入字符。:
切换到底线命令模式,以在最底一行输入命令。x
删除当前光标所在处的字符.dd
删除当前光标所在行的所有字符。gg
将光标定位到文件的开头G
将光标定位到文件的结尾^
将光标定位到一行的开头$
将光标定位到一行的结尾
若想要编辑文本:启动 Vim,进入了命令模式,按下 i
,切换到输入模式。初学者常犯的错误就是在命令模式下输入字符,必须要切换到输入模式才能输入字符!
当然,命令模式只有一些最基本的命令,因此仍要依靠底线命令模式输入更多命令。
输入模式
在命令模式下按下 i
就进入了输入模式。
在输入模式中,可以使用以下按键:
字符按键以及 Shift 组合键,输入字符;
回车键 Enter,换行;
退格键 Backspace,删除光标前一个字符;
删除键 Delete,删除光标后一个字符;
方向键,在文本中移动光标
退出 ESC,退出输入模式,切换到命令模式
底线命令模式
在命令模式下按下 :
(英文冒号)就进入了底线命令模式。底线命令模式可以输入单个或多个字符的命令,可用的命令非常多。
在底线命令模式中,基本的命令有(已经省略了冒号):
q
退出程序w
保存文件wq
保存并退出q!
不保存,强制退出
文件链接 ln
命令
ln
是 Linux 的一个
链接分为两种:硬链接 (hard link) 与软链接 (symbolic link),硬链接的意思是一个档案可以有多个名称,而软链接的方式则是产生一个特殊的档案,该档案的内容是指向另一个档案的位置。硬链接是存在同一个文件系统中,而软链接却可以跨越不同的文件系统。通常,我们使用
1 | ln [OPTION]... [-T] TARGET LINK_NAME |
硬连接只能链接在同一文件系统下的文件,既不能跨文件系统,也不能链接目录,而软链接皆可链接。
随处可见的链接(点击可以折叠)
在 Linux 中,随处可见链接,例如使用 ls -lh /
,你可以看到以下输出:
1 | total 8.1G |
在每行的开头,你会发现有一串奇怪的字符,其中第一个字符就是这个文件的属性,d
表示 directory
即目录,l
表示 link
即链接,-
表示普通文件。观察链接项,后面使用了 ->
符号表示了链接到的内容。说明在根目录下,其实 /bin
目录是 /usr/bin
的一个软链接。如果你运行 ls -lh /bin/
和 ls -lh /usr/bin/
,你会发现它们的输出一模一样!当然,如果你使用 ls -lh /bin
,ls
命令会告诉你这是一个链接。
使用链接,我们也可以像 Windows 一样创建快捷方式。
终端命令补充
以上介绍了 Linux 常用的文件处理命令,了解这些命令后,基本就可以很愉快地处理 Linux 上的文件了,也恭喜你有耐心看到这里,下面作者打算补充两个小知识点,可以让终端命令使用更加高效。
输入输出重定向
在 Linux 实际使用过程中,我们可能希望将一些命令打印的内容输出到文件,或是将一些命令的输入从文件中读取,shell 也提供了这样的方法,即使用输入输出重定向运算符 >
, >>
, <
。
1 | echo "Hello World" > hello.txt |
其中,>
直接把内容生成到指定文件,会 >>
则在文件尾部
重定向深入讲解(点击可以展开)
一般情况下,每个Linux 命令运行时都会打开三个文件
- 标准输入文件 (stdin):stdin 的文件描述符为0,Linux 程序默认从 stdin 读取数据。
- 标准输出文件 (stdout):stdout 的文件描述符为1,Linux 程序默认向 stdout 输出数据。
- 标准错误文件 (stderr):stderr 的文件描述符为2,Linux 程序会向 stderr 流中写入错误信息。
默认情况下,command > file
将 stdout 重定向到 file,command < file
将 stdin 重定向到 file。如果希望 stderr 重定向到 file,可以这样写:
1 | command 2>file |
其中,2
表示标准错误文件 (stderr)。
如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:
1 | command > file 2>&1 |
在 Linux 中,有一个特殊文件,/dev/null
,写入它的所有内容都会被直接丢弃,如果尝试从该文件读取内容,那么什么也读不到。所以,如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null
:
1 | command > /dev/null |
如果也想同时屏蔽标准错误信息,则可以写为:
1 | command > /dev/null 2>&1 |
这里的 2
和 >
之间不可以有空格,2>
是一体的时候才表示错误输出。
在一行执行多条命令
很多情况下,我们需要在同一行输入多条命令,或是根据上一条命令的结果执行一些命令,这时可以使用 &&
, ||
完成命令的连接,用法如下:
1 | command1 && command2 |
其中,&&
是如果前一条命令执行成功则执行下一条命令,即如果 command1
执行成功,则执行 command2
;||
与 &&
命令相反,执行不成功时执行后续命令,即如果 command1
执行失败,则执行 command2
。
例如我们可以使用
1 | mkdir a && cd a |
这样就可以先创建文件夹 a,如果文件夹创建成功,则进入文件夹 a。
还有一种不同寻常的命令连接方式,就是通过管道运算符 |
,使用如下:
1 | command1 | command2 |
管道运算可以将前面进程的输出(stdout)直接作为下一个进程的输入(stdin),这在一些命令使用时非常便利。
1 | ps aux | grep bash |
其中 ps aux
是显示 Linux 的所有进程,然后使用管道传递到 grep
命令,表示查找其中的 bash
字符串,这样终端就会输出 bash
进程的信息。
至此,恭喜你完成了第二章的学习!第二章主要带读者了解了 Linux 文件系统及其对应的命令,学会后,就可以愉快地操作 Linux 系统的文件了,当然,在使用过程中,你可能会遇到你没有修改某个文件的权限,或是无法进入某个目录。下面,第三章将介绍 Linux 的用户与权限控制的相关内容,让你的普通用户也能在运行一些命令时提权为管理员用户!
第三章 Linux 用户与权限控制
我们都说,Linux 很安全,这与 Linux 的用户权限控制是分不开的。在 Linux 上,没有权限意味着你没有办法读、写、执行一些文件。并且,对 Linux 而言,root 用户(特权用户)几乎能干任何事,甚至可以删除整个系统!
Linux 的权限管理,与两个重要的特性关联紧密:一切皆文件;多用户操作系统。多用户操作系统,意味着用户之间的资源需要隔离,就有了权限存在的必要性;一切皆文件,意味着权限管理的目标只有文件。
本教程主要针对 Linux 原生的权限管理机制(Discretionary Access Control, DAC),不会涉及 SELinux 的内容,如果你的服务器使用的是 SELinux 权限控制,会非常严格,这显然不在本文的讨论范围内。
用户与组
Linux 对账户和组的管理通过 ID 实现,而不是用户名。用户和组的 ID 分别对应 UID (User ID) 和 GID (Group ID)。一个用户可以属于多个组,但只能属于一个基本组,可以属于多个附加组。用户用于精确授权,组用于批量授权。
基本组和附加组的区别(点击可以展开)
基本组:如果没有指定用户组,创建用户的时候系统会默认同时创建一个和这个用户名同名的组,这个组就是基本组,不可以把用户从基本组中删除。在创建文件时,文件的所属组就是用户的基本组。
附加组:除了基本组之外,用户所在的其他组,都是附加组。用户是可以从附加组中被删除的。
sudo
命令
如果你是普通用户,那你如果要进行系统软件安装或是访问系统文件夹,sudo
会是你最常用的命令。sudo
是 superuser do 的简称,意思就是使用特权用户命令后面的命令,使用方式非常简单:
1 | sudo command |
当你使用管理员权限运行命令时,sudo
会要求你输入你的账号密码。如果你的账号没有使用 sudo
的权限,请使用管理员账号登录并使用 sudo
。
决定用户是否能使用 sudo(点击可以展开)
通过文件 /etc/sudoers
可以控制用户能否使用 sudo
。
1 |
|
文件的注释很详尽,从中可以看出,root 用户可以无限制地使用 sudo,sudo 组下的所有用户也能够使用 sudo。所以,让一个用户使用 sudo 的最好方式,就是将其添加入 sudo 组中。
创建、删除、修改用户或组
本节所有的内容都需要使用超级用户权限才能运行,也就是说,你需要可以使用 sudo
命令才能运行。如果你没有使用 sudo
的权限,也不必担心,你不需要在机器上实际运行这些指令,本教程会详细讲解其效果。
useradd
命令
useradd
可以创建一个账号,具体用法如下:
1 | sudo useradd xiao |
上述命令可以创建一个名为 xiao 的用户,前面的 sudo
说明 useradd
命令需要使用特权用户运行。
创建完成后,可以查看 /etc/passwd
文件下查看刚刚创建的用户:
1 | cat /etc/passwd |
在最后一行可以看到刚刚添加的用户,当然如果你觉得终端输出了大量的无用信息,你可以使用前面章节提到的管道运算符查找:
1 | cat /etc/passwd | grep xiao |
终端的输出为:
1 | xiao:x:1001:1001::/home/xiao:/bin/sh |
在 Linux 系统文件中,通常不同的字段用 :
分隔,所以你可以看到这个文件里面有 7 个字段,分别是 用户名:密码:UID:GID:描述信息:家目录:登录shell
注意密码字段,里面只存储了一个 x
,表示有密码,真正的密码出于安全考虑,存储在 /etc/shadow
中。另外这个账号没有描述信息,所以你看到描述信息对应的字段是空的。
如果你想更改登录 shell,可以直接修改 /etc/passwd
文件,将其改为你想要的 shell,例如 /bin/bash
,当然,更推荐你使用 chsh
命令更改。chsh 就是 change shell 的缩写,你可以使用 chsh [-s shell] [username]
修改指定用户的登录 shell。
groupadd
命令
groupadd
可以创建一个组,具体用法如下:
1 | sudo groupadd xx |
上述命令可以创建一个名为 xx 的组,前面的 sudo
说明 groupadd
命令需要使用特权用户运行。
创建完成后,可以查看 /etc/group
文件下查看刚刚创建的组:
1 | cat /etc/group | grep xx |
终端的输出为:
1 | xx:x:1002: |
可以看出,组的文件有 4 个字段,分别是 组名:组密码:GID:组内用户列表
在这里,组密码是指非本组用户切换到本组时的密码。
id
命令
id
可以查看一个用户的详情,会显示 UID,GID,以及所属的组。
1 | id xiao |
这里 xiao 用户就在很多组里面,由于其在 sudo
组中,所以 xiao 用户可以使用 sudo
。
passwd
命令
passwd
命令用于修改某个用户的密码
1 | sudo passwd xiao |
你需要使用 sudo
权限才能修改密码。注意, Linux 为了安全起见,在输入密码时并不会显示位数,所以你不会看到终端有任何改变,不用担心,大胆输入后回车即可。
usermod
命令
usermod
命令可以修改用户信息,如密码、家目录、组信息等等。这里的 mod 是 modify 的简称。
1 | sudo usermod xiao -c 好耶 |
其中常用参数如下,如果想获取所有参数,可以使用 usermod --help
1 | Usage: usermod [options] LOGIN |
userdel
, groupdel
命令
userdel
, groupdel
命令分别用于删除用户与删除组。
1 | sudo userdel xiao |
其他相关文件
上面已经介绍了 /etc/passwd
及 /etc/group
两个文件,实际上,/etc/shadow
及 /etc/gshadow
也与 Linux 用户密切相关:
/etc/shadow
文件
1 | sudo cat /etc/shadow | grep xiao |
需要注意,这个文件读取就需要超级管理员的权限,所以需要使用 sudo
,命令输出如下:
1 | xiao:Dj/alNi.YlkeDIZ0:19154:0:99999:7::: |
总计有 9 个字段,分别是 用户名:加密密码:最后修改时间:最小修改时间间隔:密码有效期:密码需要变更前的警告天数:密码过期后的宽限时间:账号失效时间:保留字段
,其中,加密密码使用了 SHA-512 散列算法,难以从散列后的值推算原来的值。因此密码存储是安全的。
/etc/gshadow
文件
1 | sudo cat /etc/gshadow | grep xiao |
需要注意,这个文件读取就需要超级管理员的权限,所以需要使用 sudo
,命令输出如下:
1 | xiao:!:: |
总计有 4 个字段,分别是 组名:组密码:组管理员名:支持的账号名
。
用户登录时的系统行为
当用户登录系统时,实际上是调用了 login
程序进行验证,首先 login
程序会对用户名进行分析:如果用户名不是 root,且存在 /etc/nologin
文件,login 将输出 nologin 文件的内容,然后退出。通过验证后,会校验用户名及密码,如果校验成功,那么会启动登录 shell。
在启动登录 shell 时,如果登录 shell 是 bash
,那么会读取对应家目录下的 .bashrc
并执行。.bashrc
由于是 .
开头的文件,所以在使用 ls
时不会显示,需要使用 ls -a
才会显示。.bashrc
中的 rc
的含义有很多种说法,常见的可以认为是 runcom, run configuration, run control 的缩写。
查看 .bashrc
的内容,你会发现一些有趣的代码:
1 | some more ls aliases |
alias
命令是别名的意思,你可以为一个较长的命令起一个简短的别名,例如,在 bash
中,你输入 ll
就相当于 ls -alF
。
利用 .bashrc 配置环境变量(点击可以折叠)
环境变量是指 shell 程序运行时能够直接使用的变量,例如:
1 | echo $PATH |
其中 PATH
就是一个环境变量,访问时在前面加上美元符号 $
即可,我们可以这样将环境变量赋值:
1 | export LD=/home/xiao/lib |
如果想在 PATH
变量中追加内容,可以这么写:
1 | export PATH=$PATH:/home/xiao/lib |
这就相当于把 /home/xiao/lib
追加到 PATH
变量后。但是这么写,有一个巨大的问题,那就是如果关闭后,重新启动一个 shell,那么辛辛苦苦配置的变量就没有了,这时,我们就可以在 .bashrc
文件末尾添加这样的 export
命令,使得环境变量在注销重新登录后依然有效。
那么类似 PATH 这样的环境变量有什么用呢?通常,在不同的 shell 程序中,可能会读取不同的环境变量,但 PATH 变量是一个很特殊的环境变量,它是 shell 查找可执行程序的路径集合。如果你想使用的程序不在 PATH 目录下,那么你就不能直接调用。你可以使用 which
命令查看当前使用的程序的绝对路径,例如:
1 | which ls |
你会发现,我们常用的 ls
命令,其实在 /usr/bin
目录下,而这个目录,正是在 PATH 环境变量里。如果你运行:
1 | export PATH= |
那么你再试试能不能使用 ls
命令了,你会发现 shell 提醒你找不到 ls 命令。这就是环境变量的作用。
偏题一下,其实 Windows 也有环境变量(点击可以折叠)
其实 Windows 系统在运行时也有环境变量,并且也有 PATH 变量。在使用命令提示符时,除了命令提示符的内置命令,大多命令也是在 PATH 中寻找,在 Windows 中设置环境变量使用 set
, setx
命令,这里不再展开。或者直接打开高级系统设置,环境变量,进行修改。需要注意备份,如果环境变量丢失,有很多程序都不能正常运行!
文件权限
我们随便查看一个文件 ls -lh /etc/passwd
:
1 | -rw-r--r-- 1 root root 1.9K Aug 16 16:30 /etc/passwd |
从左到右,依次是:
- 1 个字符,表示文件类型:
-
表示文件,d
表示目录,c
表示字符型文件,l
表示链接文件,这里是-
表示文件 - 9 个字符,表示文件权限:分别是文件所有者、文件所有人所属组、其它人的权限,依次为读、写、执行,即 rwx,如果有权限则用字母,如果没有对应的权限,则使用
-
代替,这里是rw-r--r--
表示文件所有者 root 有读写权限,同属于 root 组的用户有读权限,其他用户有读权限 - 1 个数字,表示连接计数,这里是 1
- 文件所有者,这里是 root
- 文件所属组,这里是 root
- 文件大小,这里是 1.9K
- 修改日期,这里是 8 月 16 日 16 时 30 分
- 文件名,这里是 /etc/passwd
rwx
权限很好理解,r
是 read,表示读权限, w
是 write,表示写权限, x
是 execute,表示可执行权限。我们可以通过 chmod
及 chown
命令更改文件权限。
chmod
命令
chmod
命令可以修改文件或目录的权限,是 change file mode bits 的简称。
1 | sudo chmod +x hello.sh |
这就是为 hello.sh
文件添加可执行权限。为了更好地进行权限管理,人们发明了一种计数的方法,实现快速的权限控制,其中 r
读权限等于 4,w
写权限等于 2,x
可执行权限 等于 1,如果需要几种权限,将其加起来即可,这样我们就可以用 3 个数字代表这三种权限了。例如要将 hello.sh
的权限更改为 rwxr-xr-x
,只需运行:
1 | sudo chmod 755 hello.sh |
之前使用的 chmod 600 FILE
其实就是将文件权限改为仅所有者用户可以读写,同组用户或其他用户都不可读写也不能执行。
chown
命令
chown
命令可以修改文件的所有者与所有组,是 change owner 的简称。
1 | sudo chown root:root hello.sh # 将 hello.sh 的所有者及所有组均设为 root |
至此,恭喜你完成了第三章的学习!第三章主要带读者了解了 Linux 用户与权限控制的有关内容,同时也简要涉及了环境变量,命令别名等内容,能看到这里,实属不易!目前,你已经学会了 Linux 文件处理,并且大部分的权限问题都能正确处理了。现在,我们已经可以愉快地使用 Linux 系统了。第四章就将介绍 Linux 上软件的安装与卸载,学会后,你就可以扩充自己的 Linux 命令库,使用其他人写好的,便利的程序辅助自己的开发与科研,也可以自己探索 Linux 系统了!
第四章 在 Linux 上安装 / 卸载软件
首先恭喜你看到了这里,后面的内容将会轻松不少,大多就是安装一些软件与一些好的软件的推荐。不再会有大段知识性的内容。
你可能还不清楚 Linux 软件安装的便利之处,我先询问一个问题,如何在 Windows 上安装软件?可能有人会说,有 XX 软件管家,但马上有人反驳,这个 XX 软件管家上面的软件并不是官方来源,里面有可能有捆绑或是广告,所以正确的方法应该是去找软件的官网,然后下载安装包,安装,然后配置,再运行。
实际上,这个流程听上去就非常麻烦。在 Linux 上,你就不会有这些烦恼了,因为几乎每个 Linux 发行版都内置了一个包管理器,你可以使用包管理器,输入一行命令,即可完成软件搜索、安装、卸载等等操作。相信你一定觉得很便利,下面我们就来看看如何使用 Linux 包管理器安装卸载软件。
使用包管理器
在不同的 Linux 发行版上,有不同的包管理器,例如,在 Ubuntu
上,使用 apt
管理;在 Cent OS
上,使用 yum
管理;在 Arch Linux
上,使用 pacman
管理;在 Gentoo
上,使用 emerge
管理,不一而足。这些包管理器作者都或多或少接触过,它们的使用思路其实都是相通的,本教程为了便利起见,就以 apt
包管理器为例,讲解使用方法。
首先,在使用包管理器前,应该先换源,因为一些原因,部分包的下载连接在国内无法访问,所以我们需要把包管理器的软件更新源改为国内源。对于 ubuntu
而言,访问 清华大学开源镜像站丨Ubuntu 镜像使用帮助,上面详细介绍了如何更换软件源。你需要根据 Ubuntu 的版本选择,如果你不清楚你的 Ubuntu 的版本号,可以使用 cat /etc/issue
查看。
更换软件源后,你就可以正常使用包管理器了。
1 | sudo apt update # 更新软件源,这是安装、升级包前必做的命令 |
apt
的强大之处就在于可以自动处理软件包的依赖,它会帮你安装这个软件所依赖的其他软件,免去你配置环境的苦恼。
下面举几个实际使用的例子,加深读者的理解
1 | sudo apt update && sudo apt upgrade |
1 | sudo apt update |
你会看到这样的输出:
1 | Reading package lists... Done |
apt
询问你是否继续,大写 Y
说明 Y
是默认选择,也就是说如果你想继续,可以直接回车,或者输入 y
或 Y
然后回车都可安装。如果你后悔了,那么输入 n
即可退出安装。
选择继续后,稍事等待,即可安装完成。这时,你可以在终端输入 ranger
使用刚刚安装的软件。ranger 是一个方便的文件管理软件,左右方向键可以切换上下级目录,上下键可以更改目录,这样就可以快速浏览文件了,按 Q 可以退出。
如果想要卸载 ranger 可以使用以下命令:
1 | sudo apt remove ranger # 移除 ranger 软件包 |
这就是 Linux 安装软件的基本步骤了,非常便利。如果你想安装软件,只要使用 apt
即可。那么如果我想安装一个软件,但我不清楚这个软件包的名称怎么办呢?这时可以使用 apt search
搜索。
1 | apt search python |
你会看到所有含有 python 的软件包,当然这个数量实在是太多了,我们可以使用 grep
进一步查找 python 开头的软件包
1 | apt search python | grep ^python |
比方说你找到了你想要的 python3.10
,那么就可以使用 sudo apt install python3.10
安装了。
编译安装软件
有些情况下,部分软件没有提供二进制包,也就是说,有些软件只提供了源代码,或是只有其他 Linux 发行版格式的软件包。这时,我们可以选择自行编译安装。
还有些情况,你不是系统的管理员(没有 sudo
权限),无法使用包管理器 apt
安装软件,那么你就可以使用编译安装的方法,这样,你就没有必要使用管理员权限安装软件了。
你或许认为这太麻烦,毕竟我自己写的程序还不能编译通过,我还能很容易地编译其他人的程序吗?实际上,在 Linux 下使用源代码形式发行的软件,大多编译步骤非常简单,你只需要在第一次编译前安装好编译环境,后面的操作也就相当便利了。
一般来说,编译过程可以分为两步,第一步是将源码编译为目标文件,第二步是将目标文件链接为可执行程序。其中第二步需要处理错综复杂的依赖关系,好在,Linux 有 make
命令,可以通过 Makefile 文件自动地完成链接功能。大多数软件的源代码都会自带一个 configure
脚本,他可以根据当前系统的环境生成 Makefile 文件,然后就可以愉快地使用 make
完成源代码的编译。
Linux 源码安装步骤基本可以分为 5 步:
- 获取源代码并解压
- 查看 INSTALL 或 README 文件,开发者会在文件中详细描述如果安装
- 使用
configure
命令,生成 Makefile 文件 - 编译,执行
make
命令 - 安装,执行
make install
将上一步编译好的文件安装到指定的目录或系统中
不同的软件编译安装方法可能并不相同,所以需要仔细阅读 INSTALL 或 README 文件,开发者会详细说明其编译安装的方法,以及编译所需的软件。
下面,我将以编译安装 nginx 为例,进行说明:
编译安装 nginx
- 安装编译所需的软件
在 Ubuntu 系统中,你可以使用 sudo apt install build-essential
安装基本的编译工具链。
1 | sudo apt install build-essential |
- 下载源代码并解压
在这里,我们使用 wget
命令下载源代码,如果源代码是用 git 存储库形式存储,你可以使用 git clone
命令克隆下来。
1 | wget http://nginx.org/download/nginx-1.21.4.tar.gz |
wget
命令其实就是将文件下载到当前目录下,与浏览器提供的下载功能是一样的。
1 | tar -zxvf nginx-1.21.4.tar.gz |
- 阅读安装说明
源代码解压完成后,我们进入源代码的目录,查看安装的说明
1 | cd nginx-1.21.4 |
软件告诉你查看其官网,在官网下,可以看到右侧有 Building nginx from Sources
一项,点击即可查看 相关说明。
- 生成 Makefile 文件
阅读说明后,我们可以生成 Makefile 文件了
1 | ./configure --prefix=/usr/local/nginx \ |
这里为了说明 configure 的作用,我们使用了很多个选项,这些选项的详细说明在上面的网页中可以查看,其中 --prefix
是指软件编译完后,安装的位置,这里我们设置成了 /usr/local/nginx
,这个目录通常就是 Linux 建议的用户编译软件的安装目录。
当你执行后,你会看到 configure
程序正在检查你的系统环境以及编译器的信息,如果报错 Error
的话,可以查看缺少的库,并使用软件包安装即可。在执行完毕后,你可以看到一些摘要。
1 | Configuration summary |
- 开始编译
在生成 Makefile 后,就可以使用 make
命令编译程序了。
1 | make |
如果你想多线程编译程序(默认是单核),那么你可以使用 -j
选项
1 | make -j 8 |
这里的数字 8 是指编译的线程数,如果你是 8 核的电脑,那就使用 8,请注意编译的线程数不要超过核心数,否则会影响编译效率,如果你还想在编译期间使用服务器,也不要占满核心数,否则服务器会非常卡顿。
如果没有报错,那么你会看到
1 | make[1]: Leaving directory '/home/xiao/nginx-1.21.4' |
如果不幸报错了,那么你可以自行搜索错误的信息,并进行相关配置,然后清除之前编译的内容,再重新编译
1 | make clean && make |
- 安装程序
编译完成后,你就可以使用 make install
安装。需要注意的是,之前我的安装目录设置为 /usr/local/nginx
,这个目录需要管理员才能创建,所以安装时要使用 sudo
。
1 | sudo make install |
然后你就可以正常使用 nginx 程序了,nginx 是异步框架的网页服务器,也可以用作反向代理、负载平衡器和HTTP缓存。在此处不介绍其使用。
至此,恭喜你完成了第四章的学习!第四章主要带读者了解了 Linux 上安装卸载软件的方式,相较于 Windows 系统,这种安装方式显得简单了许多,你会花更少的时间在环境的配置上,无形中提高了开发的效率。至此,读者已经掌握了 Linux 的基本内容,对于初学者而言,这些知识已经足够使用。第五章主要是介绍 Linux 的其他常用命令以及推荐一些 Linux 上很好用的软件。
第五章 Linux 常用命令及软件
恭喜你能看到这里,现在,你已经能够在 Linux 上完成几乎所有的文件操作,权限操作,也学会了安装、卸载软件,那么接下来,作者要再补充介绍几个 Linux 的常用命令,并且推荐一些 Linux 上好用的软件,让我们继续吧。
网络文件下载
在 Linux 命令行中,我们也会有下载一些网络上的文件的需求,通常,我们使用 wget
或 curl
命令下载网络上的文件。wget
在第四章 编译安装软件时已经有所涉及,使用非常简单,wget URL
就可以下载文件了。
1 | wget [option]... [URL]... |
curl
命令会默认将下载的内容输出到终端,如果你需要保存到文件,需要使用 --output
选项。
1 | curl www.baidu.com |
你会看到百度的网页源码,如果你想使用 curl 下载文件,可以这么写:
1 | curl http://nginx.org/download/nginx-1.21.4.tar.gz --output nginx-1.21.4.tar.gz |
文件上传与下载
如果你想将自己电脑上的文件上传到服务器上,或是将服务器上的文件下载到电脑上,那么可以使用 sftp (SSH File Transfer Protocol, also Secure File Transfer Protocol) 协议完成,由于这个使用代码不太优雅。所以这里推荐使用软件完成文件的上传下载。
如果你使用的终端程序自带了文件传输功能,那么当然可以使用终端自带的文件传输,如果没有,这里推荐使用 Filezilla
。其安装使用非常简单。
软件左侧是本地的文件,右侧是服务器的文件,如果要下载,可以直接使用右键单击服务器的文件或文件夹,点击下载即可,如果要上传,也只需要右击本地的文件或文件夹,点击上传即可。
系统性能监控
有时,我们需要监控系统的运行情况,例如 CPU、内存等的使用,这时,可以使用内置的命令 top
查看。
输入 top
命令后,就能看到 CPU、内存的占用,也能看到正在运行的进程,但是其界面比较丑陋,所以我们通常使用其他程序代替 top
。
例如,我们可以使用 htop
查看系统资源占用。htop
需要额外安装,运行 sudo apt install htop
即可。
htop
界面默认上部是 CPU、内存、交换空间的信息,还有电脑负载以及开启时长。下面是进程的信息。
如果你还想再极客一点,也可以使用 btop
。btop
也需要额外安装,运行 sudo apt install btop
即可。
很酷,不是吗?
如果你想要查看网络的使用情况,你当然可以查看 btop
,当然,你也可以使用 bmon
软件,运行 sudo apt install bmon
即可。
如果你想查看服务器的端口占用情况,可以使用 netstat
命令,使用 sudo apt install net-tools
安装即可。
1 | netstat -ntlp |
1 | Active Internet connections (only servers) |
你会看到服务器上所有监听的端口。
文件浏览
如果你想快速地在服务器上浏览文件,那么我推荐你使用 ranger 程序。直接使用 sudo apt install ranger
安装即可。
如果你想尝试更复杂的文件管理器,你可以使用 mc 程序,直接使用 sudo apt install mc
安装即可。
进程管理
有时,我们需要有一个类似 Windows 任务管理器一样的软件,查看 Linux 的进程,或是强行停止一些进程。在 Linux 下,你可以使用 ps
命令查看当前的进程。ps
是 process snapshot 的缩写。
1 | ps # 查看当前用户进程 |
你会发现,ps aux
的输出太长了,所以我们可以使用 grep
查找里面的进程。
1 | ps aux | grep python |
终端会输出所有的 python 进程。仔细观察输出,其有 11 个字段,依次是:
- USER 是进程运行的用户
- PID 是进程的 ID
- %CPU 是进程的 CPU 占用情况
- %MEM 是进程的内存占用情况
- VSZ 是 虚拟内存的使用情况
- RSS 是驻留集的大小,是非交换物理内存的使用
- TTY 是进程是依存于什么终端
- STAT 是进程的状态
- START 是进程启动的时间或日期
- TIME 是进程的累计 CPU 时间
- COMMAND 是进程的命令与参数
有了进程的 PID,就可以唯一确定一个进程,我们就可以对进程进行一些操作了。你可以使用 kill
命令杀死进程,命令形式如下:
1 | kill -9 PID |
例如,我在运行 ps aux | grep python
后,发现我这个 python
进程的 PID 是 10756,那么我就可以使用 kill -9 10756
杀死这个 python
进程。
由于 Linux 默认进程是依存于一个终端的,所以如果你关闭这个终端,那么进程也会停止。比如我正在用服务器计算一个东西,但是很不幸,网络断开了,这时,这个进程由于终端的关闭就会被杀死。这显然是我们不想看到的。那应该如果操作呢?我们可以使用 nohup &
命令将命令转为后台运行。
1 | nohup command & |
由于不会在终端上输出,所以 nohup
会默认将标准输出写入到 nohup.log
文件中,如果你想重定向输出,可以使用重定向运算符。
1 | nohup command > log.txt 2>&1 & |
这样就能将标准输出与标准错误都写入到 log.txt
中。举个例子:
1 | nohup python3 calculating.py > log.txt 2>&1 & |
这样就能将 python3 caculating.py
转到后台运行,也不用担心断网了。
终端复用
当然,你可能会觉得上面使用 nohup
太过麻烦,我总不能每次运行命令时都要用 nohup
包裹起来吧,而且网络是不稳定的,指不定什么时候就会掉线。在这种情况下,你可以使用终端复用工具。它的基本原理就是创建一个不依赖终端的虚拟终端进程,在你的终端关闭后,这个虚拟进程依然可以继续运行,常用的主要是 screen
工具,但是其比较古老,本教程建议使用的是 tmux
。
你可以使用 sudo apt install tmux
安装这个工具。
然后你直接输入 tmux
,就能打开一个新的终端,在里面运行的命令,在关闭终端后,仍然会运行。
tmux 小教程(点击可以折叠)
tmux
其实是一个非常好用的小工具,为其单独写一篇教程也不为过。在这里,我们就精简一下,只介绍 tmux 最实用的功能。
你可以使用 tmux
创建一个 tmux
终端。然后使用快捷键将终端分离。
注意,tmux 在未做其他配置时,默认的快捷键是由前导键和快捷键组成,你需要先按 CTRL + B 后,才能输入快捷键。
例如分离终端快捷键是 D,你需要先按 CTRL + B 后,再按 D 键。
终端分离后,你就会退回到你的终端,这时你的终端并没有被杀死,你可以用 tmux ls
命令查看所有正在运行的终端,最前面的一个数字表示终端的编号,此后你可以使用 tmux attach-session -t ID
来重新连接到这个终端。如果你想杀死这个终端,可以使用 tmux kill-session -t ID
命令。
使用 tmux 可以将一个终端变为好几个终端,你可以使用快捷键来分屏。
左右分屏:先 CTRL + B 后 %
上下分屏:先 CTRL + B 后 "
切换目前激活的部分:先 CTRL + B 后使用方向键
了解以上内容后,就可以正常使用 tmux
了,当然,如果你对 tmux
很感兴趣,也欢迎你查看作者的另一篇文章 我的 Linux 深度学习工作环境丨环境搭建教程 的终端配置,里面介绍了 tmux
的美化过程。
编程软件
相信你使用 Linux 系统大概率是为了编程,所以当然少不了编译器等等编程软件。在 Linux 上,你可以很方便的安装这些编译器:
C 语言编译器:gcc
, clang
Python 环境:python
, miniconda
如果你对深度学习感兴趣,相信你也要配置 NVIDIA 显卡,这一部分通常都是系统管理员的工作,本教程不再涉及,如果你感兴趣,可以参考作者的另一篇文章 我的 Linux 深度学习工作环境丨环境搭建教程 的深度学习环境搭建。
这里简要介绍一个代码版本控制工具 git
git
git
是代码控制的工具,使用 sudo apt install git
以安装它。当然,git
的高级使用也是较为复杂的,如果你只是单纯用来线性的控制版本,那么你只需要了解下面的命令即可,如果你对 git
很感兴趣,推荐你阅读 廖雪峰的 Git 教程,通俗易懂。
安装完成后,你需要进行 git 的基本配置,也就是填写自己的昵称与邮箱:
1 | git config --global user.name "Your Name" |
需要注意,如果你想使用 github 等等代码仓库,这个邮箱请保证与注册 github 的邮箱相同。
目的 | 命令 | 简述 |
---|---|---|
建立 git 库 | git init | |
将更改添加到暂存区 | git add FIELNAME | |
git add –all | ||
提交 | git commit –m “MESSAGE” | 提交目前所有已添加到暂存区的更改 |
查看更改日志 | git log | 可以查看每次更改记录对应的作者、日期、备注和哈希码 |
git reflog | 可以查看所有记录(包括回退之前) | |
转到某个版本 | git reset –hard 哈希码 | 输入哈希码前几位,可以与其他记录区分即可 |
只建议使用 git 工具管理文本类型的文件,因为文本类型的文件更改比较独立。
Visual Studio Code
当然你可能会觉得,在终端里编程并不优雅,虽然 vim
提供了代码补全以及很多插件支持,但对于初学者而言毕竟太不友好。这时,你可以使用划时代的文本编辑器,微软的 Visual Studio Code 利用 ssh 连接到服务器上,进行文件编辑,享受与本机编程同样的体验,如果你对这种编程方式很感兴趣,可以阅读作者的另一篇文章 我的 Linux 深度学习工作环境丨环境搭建教程,里面详细介绍了 VS Code 软件的配置并且推荐了许多高效的插件。
总结
首先恭喜各位读者看到这里,你已经学完了这篇很长的教程,现在你可以无障碍地使用 Linux 命令行(CLI)了。
当然,有些读者并不会止步于此,还想了解更多 Linux 方面的内容,或是对 shell
编程很感兴趣,作者也提供一些链接以便深入学习:
Changelog
这里记录了本页面所有的显著更改。
All notable changes to this page will be documented in here.
- 修改第五章 Linux 常用软件为 Linux 常用命令及软件;
- 在第二章中增加链接章节
ln
; - 删除了教程中的
docker
部分,因为对初学者并不友好。
完成第五章 Linux 常用软件。
完成第四章 在 Linux 上安装 / 卸载软件。
完成第三章 Linux 用户与权限控制。
完成第二章 了解 Linux 文件操作。
完成第一章 连接到 Linux 终端。
完成第〇章 什么是 Linux 命令。
完成教程大纲编写。