命令行控制#
结束进程#
SIGINT
:Ctrl-C
SIGQUIT
:Ctrl-\
SIGTERM
:kill -TERM <PID>
#!/usr/bin/env python
import signal, time
def handler(signum, time):
print("\nI got a SIGINT, but I am not stopping")
signal.signal(signal.SIGINT, handler)
i = 0
while True:
time.sleep(.1)
print("\r{}".format(i), end="")
i += 1
暂停和后台执行进程#
SIGSTOP
:Ctrl-Z
fg
: 前台继续运行bg
: 后台继续运行jobs
: 列出当前终端会话中尚未完成的全部任务pid
引用任务,pgrep
找出 pid%+任务编号
选取任务,jobs
会打印任务编号$!
最近的一个任务
&
:命令后缀使用可以直接在后台运行nohup
: 忽略SIGHUP
的封装,关闭终端,程序继续在后台运行disown
: 针对已经运行的程序,关闭终端可继续运行
终端多路复用#
tmux
#
基于面板和标签分割出多个终端窗口,可以同时与多个 shell 会话进行交互,可以分离当前终端会话并在将来重新连接。
会话 - 工作区,包含一个或多个窗口#
tmux
开始一个新的会话tmux new -s NAME
以指定名称开始一个新的会话tmux ls
列出当前所有会话<C-b> d
将当前会话分离tmux a
重新连接最后一个会话-t
指定具体会话
窗口 - 标签页,视觉上将会话分割为多个部分#
<C-b> c
创建新窗口,<C-d>
关闭<C-b> N
跳转到第 N 个窗口<C-b> p
切换到前一个窗口<C-b> n
切换到下一个窗口<C-b> ,
重命名当前窗口<C-b> w
列出当前所有窗口
面板 - 像 vim 中的分屏一样,面板使我们可以在一个屏幕里显示多个 shell#
<C-b> "
水平分割<C-b> %
垂直分割<C-b> <方向>
切换到指定方向的面板<C-b> z
切换当前面板的缩放<C-b> [
开始往回卷动屏幕。按下空格键开始选择,回车键复制选中的部分<C-b> <空格>
在不同的面板排布间切换
扩展阅读#
这里 是一份 tmux
快速入门教程, 而这一篇 文章则更加详细,它包含了 screen
命令。您也许想要掌握 screen
命令,因为在大多数 UNIX 系统中都默认安装有该程序。
课后练习#
任务控制#
-
我们可以使用类似
ps aux | grep
这样的命令来获取任务的 pid ,然后您可以基于 pid 来结束这些进程。但我们其实有更好的方法来做这件事。在终端中执行sleep 10000
这个任务。然后用Ctrl-Z
将其切换到后台并使用bg
来继续允许它。现在,使用pgrep
来查找 pid 并使用pkill
结束进程而不需要手动输入 pid。(提示:: 使用-af
标记)。sleep 10000 & pgrep sleep pkill -f sleep
-
如果您希望某个进程结束后再开始另外一个进程, 应该如何实现呢?在这个练习中,我们使用
sleep 60 &
作为先执行的程序。一种方法是使用wait
命令。尝试启动这个休眠命令,然后待其结束后再执行ls
命令。sleep 60 & pgrep sleep | wait; ls
但是,如果我们在不同的 bash 会话中进行操作,则上述方法就不起作用了。因为
wait
只能对子进程起作用。之前我们没有提过的一个特性是,kill
命令成功退出时其状态码为 0 ,其他状态则是非 0。kill -0
则不会发送信号,但是会在进程不存在时返回一个不为 0 的状态码。请编写一个 bash 函数pidwait
,它接受一个 pid 作为输入参数,然后一直等待直到该进程结束。您需要使用sleep
来避免浪费 CPU 性能。pidwait() { while kill -0 $1 # 循环直到进程结束 do sleep 1 done ls }
终端多路复用#
tmux source-file ~/.tmux.conf
配置文件生效
别名#
- 创建一个
dc
别名,它的功能是当我们错误的将cd
输入为dc
时也能正确执行。 - 执行
history | awk '{$1="";print substr($0,2)}' | sort | uniq -c | sort -n | tail -n 10
来获取您最常用的十条命令,尝试为它们创建别名。