Missing Semester 学习笔记 - Command-line Environment
Contents
本节会介绍如何同时执行多个不同的进程并追踪它们的状态,以及如何停止或暂停某个进程,同时如何使进程在后台运行。这对于后端开发人员来说是必备技能。
目录如下:
- Course overview + the shell
- Shell Tools and Scripting
- Editors (Vim)
- Data Wrangling(数据整理)
- Command-line Environment
- Version Control (Git)
- Debugging and Profiling
- Metaprogramming
- Security and Cryptography(安全和密码学)
- Potpourri(大杂烩)
- Q&A
假设我们使用sleep
命令让当前的进程睡眠20
秒,在这期间,通过不同的中断方式,则会终止进程的运行。如下所示:
|
|
第一次使用Ctrl+c终止,第二次使用Ctrl+\终止。通过提示信息可以看到这两种不同终止方式所给出的不同结果。
这是因为:这里的 shell 会使用 UNIX 提供的信号机制进行进程之间的通信。当一个进程收到信号时,该进程会停止、处理该信号,并基于该信号传递的信息来改变其执行,即软件中断。
当使用Ctrl+c时,shell 会发送一个SIGINT
信号给进程,用于中断该进程。而当使用Ctrl+\时,shell 会发送一个SIGQUIT
信号给进程,用于退出进程。
下面的sigint.py
程序能够捕获SIGINT
信号并将其忽略,但不会让程序停止。为了停止程序,需要使用到SIGQUIT
信号。
|
|
当执行该程序之后,我执行了两次Ctrl+c操作,显然程序还在运行中。然后,我执行了一次Ctrl+\操作,程序才停止运行。如下所示:
|
|
上述演示了SIGINT
信号和SIGQUIT
信号的使用,除了这俩以外,SIGTERM
是一个更加通用、优雅地退出信号,我们可以使用kill
命令发出这个信号。
此外,使用Ctrl+z则会发送一个SIGTSTP
信号,表示将进程挂起。而对于暂停或者挂起的进程,我们可以使用fg
或bg
命令让其继续执行,前者表示在前台继续执行,后者表示在后台继续执行。
此外,jobs
命令的作用是列出当前终端会话中尚未完成的全部任务。在某个命令的最后添加&
这一后缀字符,可以让该命令直接在后台运行。
如果你想让正在运行的进程转到后台运行,那么可以执行Ctrl+z,然后再输入bg
。不过需要注意的是:后台的进程仍然是当前终端的子进程,一旦关闭了终端,那么这些子进程也就随之终止了。为了防止这种情况的发生,可以使用nohup
命令。下面是一些例子:
|
|
此外,SIGKILL
是一个特殊的信号,它不能被进程捕获并且它会马上结束该进程。但它的缺点是会留下孤儿进程。
接下来介绍一个终端多路复用工具 tmux,你可以在一个终端上轻松地切换多个程序,或者分离它们,此时它们会在后台运行,并将它们重新连接到另一个终端。也就是说,当你在使用终端的时候,如果想要同时执行多个任务,在运行编辑器的同时在终端的另一侧执行某个程序。你当然可以再重新打开一个终端,但是使用终端多路复用工具无疑是最好、最方便的选择。
这里有一篇关于 tmux 的文章《A Quick and Easy Guide to tmux》,介绍了 tmux 的安装及简单使用。更加详细的文章:《tmux(1) — Linux manual page》、《Terminal Multiplexers》。
接下来是 alias 的使用,也就是别名
。例如,当你在终端输入ls -lah
的时候,这个过程有些繁琐。因此,你可以使用alias ll="ls -lah"
(注意:等号两边不能含有空格),然后在终端直接输入ll
即可。这大幅度减少了输入命令所需要的时间。
默认情况下,shell 不会保存这些别名,你需要将这些别名配置在.bashrc
文件中。像这样以.
开头的文件称为dotfile
,即配置文件
。常见的配置文件如下所示:
bash
:~/.bashrc、~/.bash_profilegit
:~/.gitconfigvim
:~/.vimrc 和 ~/.vim 目录ssh
:~/ssh/configtmux
:~/.tmux.conf
至于这些配置文件需要怎么配置或者怎么使用,你可以在 github 上找到许多 dotfile 文件,这里 也可以找到。
对于ssh
的使用,该工具可以连接到其它服务器,例如ssh foo@bar.mit.edu
,即通过用户名foo
登录服务器bar.mit.edu
(这里的服务器也可以是 IP 地址)。
有一点没有之前没有注意到的是:可以使用ssh foobar@server ls
直接在服务器server
上以用户名foobar
的身份执行ls
的命令。甚至也可以配合管道命令来使用。
此外,当我们在使用 ssh 连接到远程服务器的时候,我们可能会遇到「软件需要监听特定设备端口」的需求。如果在本地的话,则可以直接使用localhost:端口号
或127.0.0.1:端口号
。但是,通常情况下,服务器的远程端口不会直接通过网络暴露给用户。
我们可以通过端口转发的方式解决上述问题。转发方式有:本地端口转发和远程端口转发两种方式。如下图所示:
本地端口转发:
远程端口转发:
最常用的是本地端口转发,即在本地设备上某个端口建立连接并转发到远程端口上,同时远程设备上的服务监听一个端口。例如,在远程服务器上运行 Jupyter notebook 并监听8888
端口,通过建立本地9999
端口进行转发,即ssh -L 9999:localhost:8888 foobar@remote_server
。在使用时,只需要访问本地的localhost:9999
即可。
此外,对于其它的 shell 框架,比较流行的有 prezto 和 oh-my-zsh。而对于终端模拟器来说,这里展示了许多不同的终端模拟器,通过这些模拟器来对终端进行设置,除了可以配置字体、彩色主题、快捷键等功能之外,有的终端模拟器还支持 GPU 加速,例如 Alacritty 和 kitty。