终端、SSH 与文件传输¶
命令行操作¶
为什么要用命令行¶
图形界面非常方便,为什么 Linux 的用户还热衷于命令行的使用呢?
效率¶
使用命令行操作可以减少鼠标操作,我们经常可以使用一条命令来代替好几次的鼠标单击。例如如果我们想要移动某一个文件,我们要执行下面步骤:
- 打开文件所在的文件夹
../source/
- 打开目标文件夹
../dest/
- 从
../source/
文件夹拖拽文件file.txt
到../dest/
文件夹中
然而使用命令行,我们只需要执行一条指令。
$ mv ../source/file.txt ../dest/
可能在初学者看来,熟记这条指令并不容易,但是从长远上看,熟悉了命令行之后再加上有自动补全的 shell 程序,使用命令行可以节省大量时间。
自动化脚本¶
提示
脚本的使用将在第六章详细讲解。
Shell 脚本可以帮助程序员自动执行重复的任务。例如我们想自动编译运行一个 C 语言程序 main.c
,我们可以在该文件的目录新建一个脚本 run.sh
.
两个文件分别下如内容。
// main.c
#include <stdio.h>
int main() {
printf("Hello world!\n");
return 0;
}
# run.sh
gcc main.c -o main.out
./main.out
rm main.out
之后我们直接输入
$ sh run.sh
即可看到程序输出结果。
节省资源¶
图形界面对资源的消耗是不可忽略的,在绝大部分的服务器中都没有使用图形界面,节约资源。
使用命令行看上去很酷¶
影视作品中,操作命令行的总是技术高超的黑客。现在轮到你来操作命令行了,难道不是很酷的一件事情吗?
什么是 shell¶
上面所说的命令行,实际上指的就是 shell。shell 其实就是一个程序,它可以接受键盘输入的命令,然后把命令交给系统执行。现在几乎所有的 Linux 发行版都提供了一个叫 bash 的 shell 程序,相当于传统 shell 的增强版。
如何打开 shell¶
在图形界面中,我们需要另一个和 shell 交互的程序,叫做终端模拟器,简称「终端 (terminal)」。我们可以在「所有程序」找到它。
打开后如下图。
几条简单的命令¶
ls
: 列出目录的内容cd
: 更改目录pwd
: 查看当前所在的目录
更多的命令行操作我们将在第三章详细介绍。
示例 1¶
$ pwd
会打印出当前所在的目录
/home/ustc
示例 2¶
$ ls
会打印出当前目录的内容
Desktop Documents Music Pictures Public Templates Videos
示例 3¶
$ cd Desktop
$ ls
进入桌面,并打印出桌面的内容。
hi.txt
注意
显示内容与计算机文件状态有关,并不是每个人都会显示相同的内容。
终端 (Terminal) 与控制台 (Console)¶
还记得在 Unix 诞生之前由通用电器公司主持的 Multics 计划吗?对了,就是可以让用户把一套键盘显示器往墙上一插,直接连接到远端主机的计划。当时键盘和显示器连为一体,称为终端(terminal)。而主机自带的一套键盘与屏幕只能给系统管理员使用,称为控制台 (console),用来输出启动 debug 信息(现在的 Linux 系统如果因故障而不得不进入单用户修复模式,则只有一个终端 /dev/console
开启)。
然而随着时代的发展,这种模式逐渐被家庭电脑的分布式主机取代,我们不需要,也没有多套终端了,只有显示器、键盘、鼠标。但是为了向前兼容性,我们需要假装这是一个(甚至多个)终端,所以一般发行版 /dev
目录下有 7 个终端 tty1 ~ tty7
,通过 ctrl + alt + F1 ~ F7
切换键盘与显示器与哪个终端相对应。
再后来,随着时代发展,终端需要出现在图形界面上了,然而承载图形界面的也是终端,所以终端里的终端就需要终端模拟器来实现了。由此,出现在图形界面上的终端才叫终端模拟器。
注意:终端不是 Shell,尽管它们经常被弄混淆。
参考阅读: 你真的知道什么是终端吗?
壳层 (Shell)¶
但凡使用 Linux,必然要与之交互。广义上讲,能与用户交互的程序都符合 shell 的定义(比如图形界面可以识别鼠标位置信息,点击操作和键盘快捷键)。然而 Linux 本身以命令行工具为主,而 shell 狭义上就是命令行解释工具,即允许用户在一定程度上「说人话」来调用程序。
Shell 是非常重要的程序。如果发行版中根本没有 shell,用户便无法控制计算机了。
没有图形界面时,shell 一般为控制台 (tty) 的子进程,在图形界面上 shell 建立在虚拟终端 (pty, pseudo tty) 之上。顺带一提,ssh
的父进程也是一个 pty。
SSH (Secure Shell Protocol)¶
ssh & sshd¶
ssh
为客户端,可通过如下命令连接到远程服务器:
$ ssh user@host
sshd
为服务端,Linux 发行版往往会自动配置其开机启动并后台运行:
$ ps -ef | grep sshd
root 627 1 0 Mar30 ? 00:00:05 /usr/sbin/sshd -D
root 761 627 0 11:50 ? 00:00:00 sshd: hguandl [priv]
hguandl 767 761 0 11:50 ? 00:00:00 sshd: hguandl@pts/0
hguandl 845 768 0 11:50 pts/0 00:00:00 grep sshd
使用公钥登录¶
SSH 的登录需要授权,使用密码是最自然的想法。但是人也往往出于输入麻烦、难以记忆等原因,不会使用强力的密码,造成安全隐患。SSH 支持另一种登录方式——公钥,使用起来更加方便也更加安全。
用户首先生成一对公私钥,将公钥上传至服务器。用户登录时请求匹配公钥,如果匹配成功则可登入。
密码学方面的研究可以保证仅通过公钥是极难得出私钥的,目前常用的算法有两种——RSA 和椭圆曲线。
$ ssh-keygen -t ed25519 -a 100 -C "your comment"
$ ssh-keygen -t rsa -b 4096 -o -a 100 -C "your comment"
scp (secure copy)¶
SSH 还支持传输文件,可以使用 scp
工具进行:
$ scp hello.txt user@host:/path/to/hello.txt
SSH config¶
使用配置文件可以简化命令。
# ~/.ssh/config
Host mirrors
HostName mirrors.cra.moe
Port 2333
User hguandl
$ ssh mirrors
$ scp hello.txt mirrors:/path/to/hello.txt
RSYNC¶
- 可以文件权限/断点续传/增量传输
$ rsync -vha /path/to/dirA /path/to/dirB
$ rsync -vha /path/to/dirA user@host:/path/to/dirB
- 常用于大量文件/软件同步(如镜像站)
$ rsync -aHvh --no-o --no-g --stats --exclude .~tmp~/ --safe-links --exclude dists/ --timeout=120 rsync://nanomirrors.s.tuna.tsinghua.edu.cn/ubuntu/ /data/mirrors-zfs/sync/ubuntu
Windows 上的 SSH
实际生活中,我们最常见的一种场景是从我们个人 PC 上的 Windows 系统连接到服务器上的 Linux 系统。这可以通过一些 Windows 应用,例如 Xshell 实现。