写给新手的 Linux 手册 1

恰如字面意思,这是一篇写给新人的 Linux 指南,当然,不要指望从我这里得到什么详细的配置教程,最起码我没有打算在这篇文章里把你能遇到的 Linux 配置情况全部说清楚。我想在这篇文章里讲述的是一种理解方法或者说是一种 Linux 思维,换个更简单的说法是——它能在 Linux 向你吐出一堆牢骚的时候明白它在说什么,以及一个有经验的 Linux 用户这个时候会做什么,有经验的 Linux 用户是如何学习他们没有接触过的 Linux 知识的。

准备好了,就继续吧。

开宗明义(开篇劝退)

本页面不适用于如下类型人员:

  • 脑残微软粉丝

    如果你觉得微软爸爸什么都是好的或者你已经完全被微软圈养,现在关闭还来得及,微软不会让你在 Linux 下运行 VS 或者 Office 的,没必要找不痛快。

  • 认为电脑应该听我的,或者说稍微有一点不一样就觉得是 Linux 的问题的人

    我不想多说什么,如果你觉得程序员改一下按钮的样式你就不会用想骂人的话,我不想认识这样的蠢货。工具是听从你的命令去帮你解决问题的,如果它工作了,你应该感激它,如果出错了,很大程度上是你给的指令有问题。

  • 强行用 Windows 思维去使用 Linux 的人

    你不能强行用一把十字花的螺丝刀去拧一字的螺丝对吧。使用 Linux 就要有 Linux 的思维,当然用你熟悉的东西去类比是可以的,事实上我经常这么做,但是在遇到不一样的时候应该以现实情况为准,否则同第二条。

  • 没事闲的/听说这东西很少人用/打算用这玩意装X的

    如果你抱着这样的想法我劝你把这种精力放在打游戏上去,很显然你的学习动力是不长久的并且很容易演化成第二种。或者觉得这东西没有达到你想要的装X效果然后再装模作样的黑一通假装自己多么了不起——趁早滚开,Linux 用户们不是觉得 Linux 不能被批评,但前提是被批评的部分确实不好用。

因此本手册适合于那些确实有实际需求——Linux 从被创造出来就是一个务实的项目——并且能够接受新事物的新手,如果你确实想要了解这个系统的方方面面,必读的读物是鸟哥的 Linux 私房菜,虽然它看起来很厚,但是语言风趣,读下去不是很困难。

我该选择什么版本的 Linux?

和你常见的桌面操作系统不一样,Linux 本身不是一个操作系统——它只是一个操作系统内核,可以操作计算机硬件资源。我们通常把基于 Linux 内核的,由内核和其他常见的一系列软件组成的操作系统也叫做 Linux。因为大部分的组件和内核一样都是开放源代码软件,所以任何有能力的人都可以组织他们自己的操作系统,这被称为 Linux 发行版。不同发行版之间可能存在着配置上的些微差异或者用等价的软件替换掉另一部分软件,当然,它们之间大体上是相似的,学到的知识也都通用。

如果你需要从头选择一个发行版,选择的条件有以下几个:

  1. 尽量选择最新的版本,或者支持期较长的版本中的最新版本。

    过于老旧的版本通常已经失去维护,继续向下看你会发现这是很恐怖的事情。

  2. 尽量选择用户比较多的发行版本。

    使用的人数越多,代表你出现问题时可能寻找到解决方案的机率也越大。

  3. 尽量选择你更熟悉的发行版。

    这个不用多说了吧。

如果你打算在自己的电脑上使用 Linux,推荐的版本有 UbuntuLinuxMintFedoraopenSUSE

如果你打算在远程服务器上使用 Linux,推荐的版本有 DebianUbuntu Server, CentOS

特别需要注意的是 Ubuntu 16.04 之前的版本,Debian 8 之前的版本,CentOS 7 之前的版本由于时间过久,不建议现在选择,同时有些网站使用的是这些系统的开发代号而不是版本号,可自行搜索对照。如果你需要接手一台比较旧的服务器,请自己上网搜索或者参阅鸟哥网站,本手册不加讲解。

Arch Linux 或者 Gentoo Linux 一类需要使用者有较强能力的高定制性发行版不建议新人使用,如果你对自己的学习能力有信心,希望随时使用最新版本的软件,并且能够判断互联网上的消息有效期,可以考虑使用 Arch Linux,但是请务必多阅读 Arch Wiki

以上安装镜像的唯一可靠下载渠道为官方网站(已给出)或者官方指定的镜像站,请务必不要在来历不明的位置下载。

我该怎样连接到我的服务器?SSH 又是什么?

有关 SSH 的介绍来自维基百科:

Secure Shell(安全外壳协议,简称 SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。SSH 通过在网络中创建安全隧道来实现 SSH 客户端与服务器之间的连接。虽然任何网络服务都可以通过 SSH 实现安全传输,SSH 最常见的用途是远程登录系统,人们通常利用 SSH 来传输命令行界面和远程执行命令。使用频率最高的场合类 Unix 系统,但是 Windows 操作系统也能有限度地使用 SSH。2015 年,微软宣布将在未来的操作系统中提供原生 SSH 协议支持。
在设计上,SSH 是 Telnet 和非安全 shell 的替代品。Telnet 和 Berkeley rlogin、rsh、rexec等协议采用明文传输,使用不可靠的密码,容易遭到监听、嗅探和中间人攻击。SSH 旨在保证非安全网络环境(例如互联网)中信息加密完整可靠。

简单说的话,SSH 是一个协议,在操作系统上有对应的实现软件,用来在你和服务器之间传递消息,SSH 也是 UNIX 世界里最常用的远程控制协议,如果你对命令行界面有所了解,SSH 实际上是把远程 Shell 的输出传送给你,然后把你的输入传递给远程 Shell(在这里传递命令行的原因是网络通常不足以满足传递图形界面的带宽,字符更节省数据流量)。

需要注意的一点是 SSH 界面的回显是由远程计算机控制的,也就是说只有远程端收到了你的输入并返回给你确认信号之后你的屏幕上才会出现输入,这种设计避免了由于网络延迟带来的输入混乱,但也因此在网络不好的时候会产生延迟,不要认为是你的计算机卡住了。

SSH 分为两个部分,客户端程序 ssh 和服务端程序 sshd,同样地在 Linux 下面也有两个配置文件 /etc/ssh/ssh_config/etc/ssh/sshd_config,一般情况下不需要修改客户端的配置,你需要修改的是 服务器端/etc/ssh/sshd_config。同时服务器端需要将 sshd 作为一个 daemon (守护进程,可以理解为 Windows 里面的服务,在特定的时候由操作系统启动并完成一定工作的程序)启动于后台。在较新的 Linux 发行版中统一使用 Systemd 作为启动管理程序,使用下面的命令将 sshd 添加到开机启动列表并现在启动它:

1
# systemctl enable sshd --now

# 是 Shell 提示符,不要复制它,不理解往后看。

通常情况下你不需要修改 sshd 的配置,默认 sshd 会监听 22 号端口,如果你知道主机名称和主机上一个账户的名字/密码,就可以在客户机上运行:

1
$ ssh username@hostname

连接到远程主机。hostname可以是域名或者 IP 地址。

最常见的配置更改是改变 sshd 监听的端口,需要你修改 /etc/ssh/sshd_config,找到 #Port 22 这一行,删除掉前面的 # 以取消注释,然后修改 22 为你想要的值(端口范围为 0 - 65535,需要注意的是一些常见端口已经有使用比如 80 是 http 服务的端口,如果你的服务器上有这些服务运行记得避开)。之后用 systemctl restart sshd 重启 sshd 服务。如果你要连接到一个不是使用 22 端口的 sshd,使用 ssh -p xxx username@hostnamexxx 是你服务器的端口号。

ssh 还带有一个叫做 sftp 的客户端程序,可以在本机和远程之间传递文件,具体用法请自行搜索。

Shell 和终端都是什么?为什么我输入密码没有反应?

Shell 是一个程序(废话),它接受用户的指令并传递给内核,以便完成交互,常见的 Shell 有多种,互相之间基本兼容,通常指的是文字界面的 Shell,用户通过 Shell 执行各种其他程序。

Linux 是可以没有图形界面的(与 Windows 不同),没有桌面环境的情况下 Linux 会提供叫做 tty 的字符界面,但是字符界面毕竟功能有限(只能显示英文数字,不能显示中文等复杂字符),所以我们常用桌面环境下叫做终端模拟器的程序开启一个在图形环境下的字符界面模拟器来执行各种操作,这个程序简称终端 Terminal。之所以使用字符界面的原因是图形环境通常为了做到简单易用而限制了其功能,Shell 操作相对稳定高效并且能做到各种复杂的操作,并且在服务器上没有必要开启图形界面浪费资源,所以使用 Linux 务必要掌握 Shell 的用法。

最常见的 Shell 叫做 bash,一般交互方式是这样的:

1
username@hostname currentdir $ command --args filename

username@hostname currentdir $ 是提示符,每次出现它就代表现在掌握权回到了 Shell 上,你可以输入指令了,其中 currentdir 表示了你当前的路径,$ 在有些 Shell 里会显示为 %,但是当它是 # 的时候说明你现在不是一般用户而是 root 用户,需要注意的是这个提示符是可以改变样式的。

在 Linux 下你可以直接在提示符后面输入指令来进行操作,通常第一个位置是指令名称,比如 cp 代表复制,第二个位置是参数,一般以 - 开头,比如 -R 表示递归地复制子目录和目录里的文件,多个参数可以合并写比如 -Ri, 最后一般会接操作的文件名,对于复制来说,第一个是被复制的文件的路径,第二个是复制到的目的地,如果是文件表示复制过后改成这个名字,如果是目录就是将这个文件复制到那个目录下。各个部分之间用空白符分割比如空格或者 Tab,对于 Shell 而言连续的空白符会被识别为一个,如果文件名里有空格,用反斜杠转义。

常见的命令有很多,但是要介绍的是 man 这个指令,如果你不知道一个命令的用法,只需要运行 man 指令名 就可以获取到内置的帮助文件。

pwd 输出当前所在的路径。ls 指令列出目录下的文件(如果不指定目录则列出当前目录),常见的用法是 ls -alh,表示列出隐藏文件(-a),显示文件权限、所有者等详细信息(-l),将文件大小显示为人类易读格式(-h)。mv 移动文件,用法类似 cp(Linux 下没有重命名命令,将一个文件移动到另一个名字即为重命名)。rm 删除文件,要注意这个命令没有二次确认,同时 -rf 参数表示递归强制删除,慎用!

cat 输出一个文件的内容,当然这个文件最好是纯文本(和 猫 没有关系!),less 也会输出文件内容,但是它增加了翻页功能(cat 是一股脑倒出来,less 则是让你一页一页看)。

当你运行一个程序的时候,Shell 需要获取到这个文件的位置,Shell 有一个 $PATH 变量,当你只输入一个程序的名字而不是完整路径时,Shell 会逐个搜索 $PATH 的目录,这些目录大部分是系统存放可执行程序的位置。同时注意当前目录不在这个变量里,你可以使用相对路径(. 表示当前目录,.. 表示上一层目录,~ 表示家目录(这个只有 Shell 支持))如 ./a.out 运行当前目录下的文件,当然你也可以使用从根目录开始的绝对路径。

有些程序可能需要在后台运行,但是用 Shell 启动的程序一般在父进程也就是 Shell 退出的时候就会结束。对于有些没有提供以 daemon 方式运行的程序,可以尝试 screen 或者是 tmux 这一类终端复用器,他们可以保存 Shell 会话到后台,具体用法请自行搜索。

UNIX 哲学里面,如果一个程序不是以输出信息为目的或者需要显示进度信息,那么 “没有消息就是最好的消息”,没有输出是成功的,有输出一般是报错,复制粘贴谷歌一下。

最后有关不显示密码的问题,Linux Shell 下输入密码就是不显示的!!!不会显示星号或者圆点!!!这样可以保证安全。

我该如何编辑文件?怎样安装我需要的软件?

首先我在这里不会介绍 vim,不仅仅是因为我是 emacs 用户,而是因为 vim 对于新人而言实在是太难以学习了(除非你想让新手产生一串随机字符串(“Q:如何产生一串随机字符串?A:让新手退出 vim”))。新人一般是没有接触过模式化编辑器的。如果你需要编辑配置文件,使用 nano 这个程序就好了,nano filename 编辑文件就像记事本一样简单,同时它的快捷键都会列在屏幕下方。

有关安装软件,请把 Windows 安装包有关的思维全部忘掉。Linux 的软件包管理方式大概可以类比为应用商店,由于大部分的软件都是开源的,每个发行版都会维护自己的一个软件仓库,使用包管理程序就可以自动下载并安装到统一位置,安装的位置都是维护者写好的,并且在数据库里有所记录,所以不需要担心卸载的时候有残留(至于什么软件安装到系统盘会影响速度的说法更是无稽之谈)。也不太需要担心软件占用过多空间,Linux 下有良好的库共享机制,所以一般软件的体积远小于 Windows(由于 Windows 缺乏有效的包管理机制,开发者一般会将所有的依赖库打包到程序安装包,造成空间浪费)。

Linux 下的包管理主要有两种常见软件,Debian、Ubuntu、LinuxMint 使用 Debian 的 dpkgapt-get,CentOS、Fedora、openSUSE 使用 RedHat 的 rpmyum,具体使用方法请自行搜索,简单用法比如安装 nginx 使用 apt-get install nginx 或者 yum install nginx,便会自动从镜像站下载安装(镜像站是为了加快下载速度在全球各地建立的软件仓库的克隆)。

如果你需要一个软件,首先检查软件源里是否已经有这个软件,版本是否符合要求(有些发行版为了维持稳定,不会在软件源里使用最新版软件),如果没有,搜索你所使用的发行版是否有常见的第三方源包含这些软件。请把在官网下载的安装包作为最后选项使用,因为这些下载的安装包不会被包管理所管理,需要自行删除及检查残留,相比起来包管理是自动化并且可靠的。

如果你使用一个停止维护的发行版本,通常软件源已经无人维护,也就是说没人可以保证你使用的软件是安全的(甚至可能是无法使用的)。另外有关系统升级,Linux 升级的主动权掌握在你的手里(没有被 Windows 强制更新 然后 更新失败 然后 回滚 然后 回滚失败 所支配的恐惧了哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈这世界上还有什么东西比微软的更新更不靠谱的吗),并且你可以随时打断更新流程(在不影响系统的情况下)(除了内核及相关部分更新,大部份的安装操作 不需要重新启动)(服务器很少重启)。另外如果不是新版本软件有什么必须的功能,最好不要 更新服务器上的软件。如果你习惯了一个还在维护中的不是最新的软件,Linux 和开发者不会强迫你为了新功能而更新,因为这些新功能你可能不会用到,还可能影响到系统稳定性,当然,如果有安全更新比如修复了漏洞一类的最好更新一下。

root 是谁?权限是什么?为什么没有 CDDEFG 盘?

简而言之,root 是一个 UID(User ID)为 0 的特殊用户,一般用于系统管理操作,它可以操作系统的任何部分即使这些部分不是属于它的(你的我的都是我的)。因此我们不建议在日常操作中使用 root,并且需要给 root 设置复杂的密码。否则一旦入侵者掌握了 root,你的机器就变成了他的。日常使用 root 则很容易对系统造成损坏(系统不控制 root 的行为)。平时我们使用自己的用户,需要进行高权限操作比如安装软件(Linux 下安装软件是全局的也就是说你要修改不属于自己的部分)时使用 sudo 命令,sudo 会以 root 权限运行后面的命令,同时要求你输入自己的密码。但是只有列在 sudoers 文件里面的用户可以使用 sudo,具体的用法阅读 这里

权限则是用来管理用户对于文件的操作的。使用 ls -alh 的时候可以看到第一列都是文件的权限,一般看起来像是 -rwxr-xr-x,每一位是一个信息,内容如下:

  1. 第一位表示的是文件类型,- 表示这是一个普通文件,l 表示这是一个连接文件(link),d 表示这是一个目录(dir)。

  2. 第二到四位是文件所有者对于文件的权限(ls -l 的第三列是文件所有者),r 表示可以读,w 表示可以写,x 表示这个文件是可以运行的(当然能不能运行还要看文件内容,比如图片当然不能执行了)。如果没有某项权限,该位置为 -

  3. 第五到八位是文件所属用户组对于文件的权限,含义同上。

  4. 最后三位是既不是所有者也不属于该用户组内的其他用户对于文件的权限。

如果你需要修改一个文件的权限(前提是你对这个文件有写权限),使用 chmod num file,其中 num 对应原则如下:

  • r => 4,w => 2, x => 1

  • 每一组加起来获得一个和,第一位不考虑,例如 -rwxr-xr-x 除去第一位,换算成 755

如果想递归改变一个目录,使用选项 -R

任何情况下 不要 将文件权限设置为 777 虽然你可能看到网络上有些不会用 Linux 的蠢货为了方便这样做,这意味着任何人都有权限修改这个文件,一旦入侵者在其中加入恶意代码,而你使用 root 执行了它,那么恶意代码就有了 root 权限,可以破坏或窃取任何数据。

有关目录结构:Linux 使用目录树组织目录结构,与 Windows 不同,如果你需要访问一个设备上的文件,你需要把设备挂载到某个目录(相当于把设备自己的树枝接到总树上的某一枝干上,当然接到哪里不一定是固定的),Linux 下有一些约定的结构,通常我们把 /(根目录)放在一个分区上(其他目录都是接在根目录下面),然后把 /home 放在另一个分区里(通常储存了用户们自己的文件),这样一旦需要重新安装,只需要清空根目录所在分区,保留用户数据文件(同时把自己的文件不放在自己的家目录也是不明智的)。更多复杂的解释参见 这里这里

如何管理系统?

现在的发行版通常使用 Systemd 作为启动后的第一个进程,并且由它后台管理启动项,因此如果你使用的是我所列出的较新发行版本,一旦上网搜索到的说明让你使用 rc.local/etc/init.d/xxx start,直接关掉,他们过时了。

一般你所需的开机启动的程序比如 http 服务器 nginx,在打包的时候都会有一个 service 文件供 Systemd 使用,Systemd 主要通过 systemctl 这个指令来控制,常见用法如下:

  • systemctl enable nginx 表示将 nginx.service 添加到启动列表里(.service 可以省略),如果想同时立刻启动它,在后面附加参数 --now

  • systemctl start nginx 表示立即启动 nginx(并不影响系统重启后的操作。)(这里的启动是指由 Systemd 管理,并不是 Shell,可以理解为后台服务)。

  • systemctl stop nginx 立即停止 nginx

  • systemctl disable nginxnginx 从开机启动列表里去除,也即下一次启动系统时不启动它。加上 --now 可以同时停止它。

  • systemctl status nginx 查看 nginx 当前的运行状态信息。

如果要阅读日志,使用 journalctl 命令。更多详细介绍参见 这里

提问的艺术

Linux 开发者们一般都是凭借兴趣和对写程序的热情进行开发的,或者说他们不像微软和苹果的员工拿了你的钱替你解决问题,唯一让他们解决问题的动力就是写出完美的程序。因此一旦你发现了问题求助于他们,请注意你的语气,这里没有人亏欠你什么,最好进行建设性的发言,并且给出足够的信息,方便其他人帮你解决。如果一上来就吐槽但是问题却是你自己的话,做好挨骂的心理准备。

最后,有关 “世界上最好的两种语言” Python……

所有使用 Python 却不指明具体版本的人都是耍流氓!

由于 Python2 和 Python3 语法任性的不兼容,而有些发行版默认的 python 链接到 python3 有些还抱着 python2,建议在运行有关指令时使用具体的 python2 或者 python3 而不是 python。同样,使用 pip(Python 的包管理器,安装 Python 一些库的时候尽量用这个)的时候也要指定 pip2 或者 pip3(Python 两个版本有不同的目录,装错了没人管你)。

不要修改系统默认的 Python 版本,除非你想让用 Python 编写的系统软件崩溃!

虽然我是不建议使用 Python2 这个即将停止支持的语言,但是只要你编写的时候加上文件头:

1
#!/usr/bin/env python2

就不会造成太大问题(Python3 用户把 python2 换成 python3)。

最后,Linux 下的文件请一律使用 无 BOM 的 UTF-8 编码(自己查这是什么!)。

不懂的一定要多搜索!搜索引擎(谷歌,必应)是好工具,不搜索永远也学不会。

AlynxZhou

A Coder & Dreamer

既然看了喵写的文章,不打算投喂一下再走吗?哼!