Linux DevOps 中常用命令與技巧清單
# Linux DevOps 中常用命令與技巧清單

初接觸 Linux 時即需要通過 Shell 進行交互控制,而所謂的 Shell 即是用戶和 Linux(內核)之間的接口程序,其可以被看做命名語言解釋器(Command-Language Interpreter )。Shell 也可以被系統中其他有效的 Linux 應用程序所調用。Shell 首先判斷是否為內部命令,然后在搜索路徑($PATH )里尋找這些應用程序;搜索路徑是一個能找到可執行程序的目錄列表,如果你鍵入的命令不是一個內部命令并且在路徑里沒有找到這個可執行文件,將會顯示一條錯誤信息。而如果命令被成功的找到的話,Shell 的內部命令或應用程序將被分解為系統調用并傳給 Linux 內核。
而 Bash(Bourne Again Shell) 則是 Bourne Shell(Sh) 的擴展,其優化了原本用戶輸入處理的不足,提供了多種便捷用戶輸入的方式。在 Windows 10 之后其內置了 Linux 子系統,不過在老版本的 Windows 中我們還可以使用 [Git Bash]()、[Babun]()、[Cash (JavaScript)]() 這些工具來模擬執行 Shell 命令。
本文參考資料包括但不限于:[the-art-of-command-line](https://parg.co/bXZ)、[Linux Commands Cheat Sheet](https://parg.co/Uqu),更多參考資料請前往 [Linux Reference, Linux Shell Reference, Docker Reference, Git Reference]() 查看鏈接索引。相較于這些參考資料本文希望能夠更為生動詳細,并且不僅僅局限于 Bash 本身,而是包含具有一定價值的其他擴展命令,從而更貼近于日常工作中的需要;鑒于篇幅限制,我們在日常操作中還會經常使用 [Git CheatSheet, Docker CheatSheet](https://parg.co/Uqh) 等。
# 命令執行
## 命令輔助
### 幫助文檔
當我們對于某個命令不甚熟悉的時候,可以使用 `man bash` 查看說明文檔,使用 `Tab` 查看推薦參數或者指令。使用 `man ascii` 查看具有十六進制和十進制值的 ASCII 表;`man unicode`,`man utf-8`,以及 `man latin1` 有助于你去了解通用的編碼信息。
[tldr](https://github.com/tldr-pages/tldr/) 能夠為我們提供直觀的命令解釋與示范用法。
```sh
lsof
Lists open files and the corresponding processes.
Note: Root privileges (or sudo) is required to list files opened by others.
- Find the processes that have a given file open:
lsof path/to/file
- Find the process that opened a local internet port:
lsof -i :port
...
```
### 輸入輔助
使用 `ctrl-w` 刪除最后一個單詞,使用 `ctrl-u` 刪除自光標處到行首的內容,使用 `ctrl-k` 刪除自光標處到行末的內容;使用 `ctrl-b` 與 `ctrl-f` 按字母進行前后移動;使用 `ctrl-a` 將光標移動到行首,使用 `ctrl-e` 將光標移動到行末。
為了方便編輯長命令,我們可以設置自己的默認編輯器(系統默認是 Emacs),`export EDITOR=vim`,使用 `ctrl-x ctrl-e` 會打開一個編輯器來編輯當前輸入的命令。
對于較長的命令,可以使用 `alias` 創建常用命令的快捷方式,譬如 `alias ll = 'ls -latr'` 創建新的名為 `ll` 的快捷方式。也可以使用 `{...}` 來進行命令簡寫:
```sh
# 同時移動兩個文件
$ mv foo.{txt,pdf} some-dir
# 會被擴展成 cp somefile somefile.bak
$ cp somefile{,.bak}
# 會被擴展成所有可能的組合,并創建一個目錄樹
$ mkdir -p test-{a,b,c}/subtest-{1,2,3}
```
### 工作路徑
`cd` 命令可以切換工作路徑,輸入 `cd ~` 可以進入 home 目錄。要訪問你的 home 目錄中的文件,可以使用前綴 `~`(例如 `~/.bashrc`)。在 `sh` 腳本里則用環境變量 `$HOME` 指代 home 目錄的路徑。
而在 Bash 腳本中,同樣可以使用 `cd` 命令切換工作目錄,但是對于那些需要臨時切換目錄的情景,我們可以使用小括號進行控制:
```sh
# do something in current dir
(cd /some/other/dir && other-command)
# continue in original dir
```
## 命令連接
如果我們希望僅在前一個命令執行成功之后執行后一個命令,則需要使用 && 命令連接符:
```sh
cd /my_folder && rm *.jar && svn co path to repo && mvn compile package install
# 也可以寫為多行模式
cd /my_folder \
&& rm *.jar \
&& svn co path to repo \
&& mvn compile package install
```
如果我們希望能夠無論前一個命令是否成功皆開始執行下一個命令,則可以使用 ; 分隔符:
```sh
cd /my_folder; rm *.jar; svn co path to repo; mvn compile package install
```
### 參數切割
使用 `xargs` 將長列表參數切分為可用的短列表,常用的命令譬如:
```sh
# 搜索名字中包含 Stock 的文件
$ find . -name "*.java" | xargs grep "Stock"
# 清除所有后綴名為 tmp 的臨時文件
$ find /tmp -name "*.tmp" | xargs rm
```
### 后臺運行
當用戶注銷 (logout) 或者網絡斷開時,終端會收到 HUP (hangup) 信號從而關閉其所有子進程;我們可以通過讓進程忽略 HUP 信號,或者讓進程運行在新的會話里從而成為不屬于此終端的子進程來進行后臺執行。
```sh
# nohup 方式
$ nohup ping www.ibm.com &
# screen 方式,創建并且連接到新的屏幕
# 創建新的偽終端
$ screen -dmS Urumchi
# 連接到當前偽終端
$ screen -r Urumchi
```
## 環境配置
### 默認執行
默認的 Bourne Shell 會從 `~/.profile` 文件中讀取并且執行命令。而 Bash 會從
~/.profile is the place to put stuff that applies to your whole session, such as programs that you want to start when you log in (but not graphical programs, they go into a different file), and environment variable definitions.
~/.bashrc is the place to put stuff that applies only to bash itself, such as alias and function definitions, shell options, and prompt settings. (You could also put key bindings there, but for bash they normally go into ~/.inputrc.)
~/.bash_profile can be used instead of ~/.profile, but it is read by bash only, not by any other shell. (This is mostly a concern if you want your initialization files to work on multiple machines and your login shell isn't bash on all of them.) This is a logical place to include ~/.bashrc if the shell is interactive. I recommend the following contents in ~/.bash_profile:
```sh
if [ -r ~/.profile ]; then . ~/.profile; fi
case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
```

### 歷史記錄
最常用的歷史記錄檢索方式就是使用 `history`:
```sh
# 順序查看
$ history | more
1 ?2008-08-05 19:02:39 service network restart
2 ?2008-08-05 19:02:39 exit
3 ?2008-08-05 19:02:39 id
4 ?2008-08-05 19:02:39 cat /etc/redhat-release
# 查看最新的命令
$ history | tail -3
```
反饋的命令記錄中存在編號,我們可以根據編號來重復執行歷史記錄中的命令:
```sh
$ !4
cat /etc/redhat-release
Fedora release 9 (Sulphur)
```
我們也可以使用 Control+R 來進行交互式檢索:
```sh
$ [Press Ctrl+R from the command prompt,
which will display the reverse-i-search prompt]
(reverse-i-search)`red': cat /etc/redhat-release
[Note: Press enter when you see your command,
which will execute the command from the history]
```
使用 `history -c` 能夠清除所有的歷史記錄,或者設置 HISTSIZE 環境變量以避免記錄:
```sh
$ export HISTSIZE=0
$ history
# [Note that history did not display anything]
```
`history` 命令往往只會記錄用戶交互式的命令內容,更詳細的操作記錄可以使用 `more /var/log/messages` 查看記錄文件。
## Tmux
# 用戶權限
## SSH
### 密鑰管理
```sh
# 生成名為 id_rsa 的私鑰文件和名為 id_rsa.pub 的公鑰文件
$ ssh-keygen -t rsa
# 指定 4096 位的長度
$ ssh-keygen -b 4096 -t rsa
```
生成的 id_rsa.pub 公鑰文件也可以用于配置 Git 倉庫的 SSH 訪問等。
### 用戶登錄
我們可以使用 ssh 登錄到本機(切換用戶)或者遠端 Linux 設備中,通過將本機生成的公鑰文件寫入目標機器的 authorized_keys 即可以實現免密碼登錄:
```sh
# 指定登錄端口
ssh root@{host} -p{port}
# 上傳公鑰進行免密碼登錄
touch ~/.ssh/authorized_keys
cat -n ~/.ssh/rsa.pub ~/.ssh/authorized_keys
# 使用 ssh-copy-id 添加公鑰
ssh-copy-id username@remote-server
```
## 用戶管理
將 shell 切換為其他用戶,使用 `su username` 或者 `sudo - username`。加入 `-` 會使得切換后的環境與使用該用戶登錄后的環境相同。省略用戶名則默認為 root。切換到哪個用戶,就需要輸入*哪個用戶的*密碼。
# 文件系統
## 文件操作
### 創建
```shell
# 創建文件夾
mkdir
# 遞歸創建父文件夾
mkdir -p / --parents backup/old
# 創建文件夾時同時指定權限
mkdir -m a=rwx backup
mkdir -p -m 777 backup/server/2011/11/30
```
### 移動
### 壓縮
```sh
# 將文件解壓到指定文件名
$ tar -xvzf fileName.tar.gz -C newFileName
# 將文件夾壓縮到指定目錄
$ tar -czf target.tar.fz file1 file2 file3
```
## 文件檢索
* 可以使用 `ls -l` 查看目錄下文件列表如統計 /home/han 目錄 ( 包含子目錄 ) 下的所有 js 文件則: ls -lR /home/han|grep js|wc -l 或 ls -l "/home/han"|grep "js"|wc -l
### 文件名搜索
可以使用 [fzf](https://github.com/junegunn/fzf) 進行交互式檢索,在[這里](https://github.com/junegunn/fzf-bin/releases)下載二進制文件
```sh
$find * -type f | fzf > selected
```

### 文件內容搜索
[這篇](http://www.hostingadvice.com/blog/tutorial-use-ack-grep-linux/)文章對于 grep 與 ack 有較為詳細的介紹
[ag](https://github.com/ggreer/the_silver_searcher)
## 文件屬性
使用 `fuser tmpFile.js` 查看指定文件被進程占用情況,
## 磁盤管理
* 查看磁盤狀態
```sh
# 查看磁盤剩余空間
$ df -sh
```
```s
Device: ? ? ? ? rrqm/s ? wrqm/s ? ? r/s ? ? w/s ? ?rkB/s ? ?wkB/s avgrq-sz avgqu-sz ? await ?svctm ?%util
wrqm/s:每秒這個設備相關的寫入請求有多少被Merge了。
rsec/s:每秒讀取的扇區數;?判斷磁盤在讀還是寫
wsec/:每秒寫入的扇區數。
rKB/s:The?number?of?read?requests?that?were?issued?to?the?device?per?second;
wKB/s:The?number?of?write?requests?that?were?issued?to?the?device?per?second;
avgrq-sz?平均請求扇區的大小
avgqu-sz?是平均請求隊列的長度。毫無疑問,隊列長度越短越好。
await:??每一個IO請求的處理的平均時間(單位是微秒毫秒)。這里可以理解為IO的響應時間,一般地系統IO響應時間應該低于5ms,如果大于10ms就比較大了
%util:?在統計時間內所有處理IO時間,除以總共統計時間
```
# 文件讀寫
## 讀取
`tailf` 命令類似于 `tail -f`,其可以打印出文件的最后十行內容,并且會隨著文件的增長而自動滾動;不過其不會在文件沒有變化的時候去頻繁訪問文件。
## Vim
### 搜索匹配與替換
Vim 中可以使用 `:s` 命令來替換字符串:
```sh
:s/vivian/sky/ 替換當前行第一個 vivian 為 sky
:s/vivian/sky/g 替換當前行所有 vivian 為 sky
# n 為數字,若 n 為 .,表示從當前行開始到最后一行
:n,$s/vivian/sky/ 替換第 n 行開始到最后一行中每一行的第一個 vivian 為 sky
:n,$s/vivian/sky/g 替換第 n 行開始到最后一行中每一行所有 vivian 為 sky
:%s/vivian/sky/(等同于 :g/vivian/s//sky/) 替換每一行的第一個 vivian 為 sky
:%s/vivian/sky/g(等同于 :g/vivian/s//sky/g) 替換每一行中所有 vivian 為 sky
```
# 系統進程
## 系統檢視
### 版本型號
* 使用 `hostname` 查看當前主機名,使用 `sudo hostname newName` 修改當前主機名
* 查看 Linux 系統版本
```bash
# 查看內核版本
$ cat /proc/version
Linux version 2.6.18-238.el5 (mockbuild@x86-012.build.bos.redhat.com) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-50)) #1 SMP Sun Dec 19 14:22:44 EST 2010
$ uname -r
2.6.18-238.el5
$ uname -a
Linux SOR_SYS.99bill.com 2.6.18-238.el5 #1 SMP Sun Dec 19 14:22:44 EST 2010 x86_64 x86_64 x86_64 GNU/Linux
# 查看 Linux 發行版本
$ lsb_release -a
$ cat /etc/issue
Red Hat Enterprise Linux Server release 5.6 (Tikanga)
Kernel \r on an \m
$ file /bin/bash
/bin/bash: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped
```
### 運行狀態
我們可以使用 `uptime` 或者 `w` 來查看當前用戶的接入時間:
```sh
$ w
# 15:33:49 up 58 days, ?5:45, ?1 user, ?load average: 0.12, 0.15, 0.22
# USER ? ? TTY ? ? ? ?LOGIN@ ? IDLE ? JCPU ? PCPU WHAT
# root ? ? pts/1 ? ? 15:15 ? 49.00s ?0.04s ?0.00s w
```
## 內存
## 進程
### 進程監控
* 使用 `pstree -p` 查看當前進程樹,使用 `ps -A` 查看所有進程信息,使用 `ps -aux` 查看所有正在內存中的程序,使用 `ps -ef` 查看所有連同命令行的進程信息;使用 `ps -u root` 顯示指定用戶信息;使用 `ps -ef | grep ssh` 查看特定進程。
使用 `top` 查看進程資源占用情況,也可以使用擴展 `htop` 或者 `gtop`,如果針對容器監控,可以使用 [ctop](https://github.com/bcicen/ctop)。
```sh
# 指定查看用戶
$ top -u oracle
# 欄目內容解釋
# PID:進程的ID
# USER:進程所有者
# PR:進程的優先級別,越小越優先被執行
# NInice:值
# VIRT:進程占用的虛擬內存
# RES:進程占用的物理內存
# SHR:進程使用的共享內存
# S:進程的狀態。S表示休眠,R表示正在運行,Z表示僵死狀態,N表示該進程優先值為負數
# %CPU:進程占用CPU的使用率
# %MEM:進程使用的物理內存和總內存的百分比
# TIME+:該進程啟動后占用的總的CPU時間,即占用CPU使用時間的累加值。
# COMMAND:進程啟動命令名稱
```
```sh
$ npm install gtop -g
```

### 進程關閉
```sh
$ pkill -f java
```
# 網絡
## 狀態
```sh
# 查看指定端口的占用情況
$ lsof -i:80
# 查看某個進程的 TCP 連接
$ lsof -p
```
## 配置
## 請求
Linux DevOps
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。