命令行控制#
結束進程#
SIGINT
:Ctrl-C
SIGQUIT
:Ctrl-\
SIGTERM
:kill -TERM <PID>
#!/usr/bin/env python
import signal, time
def handler(signum, time):
print("\n我收到了 SIGINT,但我不会停止")
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
將其切換到後台並使用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
來獲取您最常用的十條命令,嘗試為它們創建別名。