Overview of Content
探索命令行界面,從基礎入門到高級應用,了解各種 Shell 類型、命令的差異以及多 Shell 關係(Shell and sub shell),我們分為以下小節來介紹
- 進入/認識命令行:深入探索控制台終端和圖形介面終端,讓您全面了解命令行的入口和使用方式
- Shell 類型:辨別並介紹常見的 Shell 類型,幫助您選擇最適合自己需求的 Shell
- 命令的差異:分析內建命令和外部命令的差異,並探討它們的使用場景和效果
- 多Shell關係:更進階的瞭解 Sub Shell (子Shell) 的概念,掌握進程列表、前後景執行和創建 Sub Shell 的技巧
- Builtin Shell 應用:探索內建命令的應用,包括歷史命令和命令別名,提高命令行操作效率
個人程式分享時比較注重「縮排」,所以可能不適合手機的排版閱讀,建議切換至「電腦版」、「平板版」視窗看 😀
寫文章分享不易,如有引用參考請詳註出處,如有指導、意見歡迎留言(如果覺得寫得好也請給我一些支持),感謝 😀
認識命令行 CLI
在 Linux 四大組件的圖型化桌面出現之前,要與系統通訊的手段就只有 Shell 命令行 (CLI
, Command line interface
),命令行大多是文本或是簡單的圖形
控制台終端
● 進入控制台終端 CLI 的方式是一種讓 Linux 系統「退出圖型化桌面」模式,進入文本模式的模式(在 CLI 模式下只會有簡單的文本,沒有圖形介面);這種模式也稱為 控制台終端
● Linux 發行版中,在系統啟動時就會啟動 5~6 個虛擬控制台
虛擬控制台終端是沒有 GUI(out the GUI
) 的 CLI 終端(控制台終端)
● 那 啞終端 是什麼?
沒有 GUI 系統,只有簡單的通訊線、螢幕、鍵盤連接到 Unix 系統上,並與其通訊,透過下指令 & 查看輸出結果來達到目的
所以控制台中端可以算是啞終端的一種形式
● Linux 系統在啟動時會創建多個 Linux 控制台終端,之後就會自動幫我們切換到圖形化終端介面(GUI CLI)
A. 通常要切換回控制台終端可以用以下快捷鍵
Ctrl
+Alt
+F1~F7
(要試試看,在其中一個)
●
tty
是啥?螢幕上見到的關鍵字
tty
代表的是teletypewriter
(電傳打字機) ,但不是每個 Linux 發行版上都會在登入介面上顯示虛擬控制台 tty 號這 Unix 設備中看到的
tty/*
、pts/*
、tty
都是終端設備,這種設備就是典型的 非硬體設備,是透過記憶體模擬出來的設備!就是軟體模擬出來的假設備(假硬體)
B. 在圖形界面終端也可以透過指令來,進入文字模式的控制台,指令如下
## sudo chvt <終端台>
## 開啟一號控制台終端
sudo chvt 1
控制台終端 getty & login
● getty
是一個 Linux 系統中的程序,它是一種用於終端的登錄程序。它通常在 Linux 系統啟動時被初始化,並負責為每個終端設備提供登錄界面
"
getty
" 是 "get tty
" 的縮寫,它接受用戶的用戶名和密碼,並驗證登錄憑據
● 它的主要作用是與終端設備進行通信,並提供用戶登錄的功能。一旦用戶成功登錄,getty
會將用戶的登錄會話交給 shell 進程處理
●
getty
是為控制台終端(純終端)服務,還是為圖形化終端服務?
getty
是為控制台終端(純終端)服務,並在控制台中呼叫 login 程式,登入成功後才呼叫 Shell
在 Linux 系統中,getty 通常與其他程序(如 init 或 systemd)一起使用,以提供完整的登錄和會話管理功能
圖形介面終端
● 透過 Linux 圖形化界面也可以進入終端;這種模式稱為 終端仿真包(模擬控制台終端);終端仿真包只是 Linux 圖形化介面其中一個元素
圖形化終端由以下解個重點部分組成
圖形化角色 | 常見的產品 | 簡介 |
---|---|---|
客戶端(GUI Client) | 圖形化終端仿真、桌面環境、遊覽器 | 請求圖型化服務的應用 |
顯示服務器(GUI Server) | Mir、Wayland Compositor、Xserver | 負責管理顯示、輸入設備(鍵盤滑鼠觸控... 等等) |
窗口管理器 | Compiz、Metacity、Kwin | 為每個窗口建立邊框、拖曳... 等等基本功能 |
部件 | Athenal(Xaw)、X Intrinsics | 客戶端添加菜單 & 外部功能 |
● 圖形化終端仿真器:in the GUI 的 CLI 終端(圖形化終端)
Ubuntu 圖形化終端介面 (下圖黑色視窗)
Shell 類型
不同種類型的 Shell 會有不同特色(或是使用限制、規範)
在腳本中會宣告在最前面(#!
符號,又稱為 shenang
),用來說明該腳本要使用哪個 Shell 解釋
常見的 Shell 解釋器
● 透過 /etc/passwd
可以知道每一個用戶的 shell 類型,不同的用戶類型可能會使用不同的 Shell 解釋器(別的小節會說明),而常見的 Shell 解釋器就是 bash
當然,除了 bash 之外,還有另外幾種常見的 bash,如下表所示
Shell 類型 | 特性 | 補充 |
---|---|---|
Bourne shell | Unix 版本的 Shell | - |
bash shell | GNU 模仿 Bourne shell 的產品,這是最常見的 Shell (默認 Shell) | - |
ash | 運行在內存受限的輕量級 Shell (與 bash shell 相容) | Debian 版本 |
korn | 支持浮點數、高級編程特性 (與 Bourne shell 相容) | - |
tcsh | 擁有 C 語言特性的 Shell | CentOS 使用,來源於最初的 C shell;CentOS 中是軟連結,連接 tcsh |
zsh | 結合多個 Shell 特性(bash shell, korn, tcsh...) | - |
進一步認識 Shell
shell 的意思是命令行界面(也可以理解為 shell 是執行命令行的應用程式)
Unix 系統中有很多重要的部份其實都是 shell 腳本
● Unix 中的 Shell 有為很多種,它們都是 基於 Bourne shell (
/bin/sh
),這是貝爾實驗室開發的標準 Shell● Linux 常用的則是 Bourne again shell,也就是 Bash shell
你的帳戶使用哪個 Shell?
● 查看 /etc/passwd
文件,並找到自己的帳戶名稱,查看最後一個欄位,該欄位就是這個帳戶預設使用的 Shell
tail /etc/passwd
查看 Bash 指令:man 手冊 / info / help
● man
指令用來查看 Linux 系統上的手冊,其格式如下
## 格式 man <command>
## 查看 man 這個指令的操作手冊
man man
按下
q
就會退出說明手冊
man 手冊的
DESCRIPTION
部份是很好的介紹,使用新指令時最好讀一下
● man 指令常用 options
options | 說明 |
---|---|
-k | 使用關鍵字找尋對應指令 |
## 查看 hostname 相關指令
man -k hostname
可以看到列出的列表中,後面有一個括號,中間對應的數字代表了這個命令在 man 手冊中的哪個位置(區);不同數字可以概述該指令的是屬於哪個部份的功能,區對應的號碼、功能如下表所示
區域號 | 說明 |
---|---|
1 | 可執行程式 or shell |
2 | 系統調用 |
3 | Library 調用 |
4 | 特殊文件 |
5 | 文件格式與約定 |
6 | 遊戲 |
7 | 概覽、約定與雜項 |
8 | 超級用戶、系統管理員命令 |
9 | 內核歷程 |
## 進入區號 5 的說明
man 5 hostname
● 其他兩個 info
, help
指令也可以拿來查看指令的操作
## info <指令>
info hostname
## <指令> --help
hostname --help
● 並非每一個命令都會有
man
、info
、help
功能,需要查詢的時候可以都試試看
認識指令錯誤訊息
● 當指令出錯時,Shell 會回覆一個「錯誤訊息」,而這個些錯訊息也保含了重要資訊;以下是一個標準錯誤訊息
# 錯誤訊息
ls: cannot access /qq123: No such file or directory
錯誤訊息以
:
符號個別分開,說明如下表所示
錯誤訊息 | 說明 | 說明 |
---|---|---|
ls | 錯誤命令 | ls 這個指令執行時發生錯誤 |
cannot access /qq123 | 檔案路徑 | 無法訪問 /qq123 這個檔案 |
No such file or directory | 具體錯誤訊息 | 沒有這個檔案或是資料夾 |
● 「警告訊息」、「錯誤訊息」一樣嗎?
「警告訊息」、「錯誤訊息」是兩種不同的訊息;出現警告訊息程式仍可運作(只是提示你哪裡出現問題),但出現錯誤訊息時指令就會停止
● 其中常見的具體錯誤訊息如下表
錯誤訊息 | 說明 | 補充 |
---|---|---|
No such file or directory | 存取不存在的檔案或目錄 | Unix I/O 系統對檔案、目錄不做區分 |
File exists | 創建檔案或目錄,但已有相同名稱的存在 | - |
Not a directory, Is a directory | 錯把目錄當成檔案來存取操作 | - |
No space left on device | 硬碟空間不存 | - |
Permission denied | 權限錯誤 | - |
Operation not permitted | 當我們試圖中止一個無權中止的程序時 | - |
Segmentation fault, Bus error | 程式嘗試存取無權存取的記憶體空間時,系統會中止該操作 | Segmentation fault 程式異常、Bus error 代表存取記憶體有問題 |
Shell 標準輸入輸出
● Unix 程序使用 I/O 資料流來讀寫資料,輸入流可以是從檔案、設備、終端... 等等來源,而 輸出流也可以將數據輸出到檔案、設備、終端... 等目的
● 標準輸入(Standard input
):
可以透過 cat 命令來測試,輸入 cat 命令後(並不指定讀取檔案),它就會讀取使用者的資料數據輸入,這樣 cat 命令就變成了標準輸入
● 標準輸出(Standard output
):
核心會為每個應用程序提供一個標準輸出流,讓他們輸出資料(並不一定會輸出到螢幕上,也可以輸出到裝置、文件)
命令的差異:內、外命令
內建、外部命令的操作方式不同,可以透過 type
判斷命令是內部還是外部的
builtin 內建命令:直接啟動
● 內建命令 不需要 啟動子進程就可以運行內建命令,我們同樣可以使用 type
命令去判斷指定的命令是否是內建命令(內建命令會顯示 builtin
)
type cd
type exit
● 命令可能會重複(內部、外部使用同一個命令),這時就可以使用
type -a <命令>
## 查看所有的 echo 命令 type -a echo
如果需要指定某個命令,那就需要寫出那個命令的具體位置;(eg.
/bin/pwd
)
外部命令:另外啟動
● 外部命令在執行時會 產生一個「新的子進程」去運行外部命令,這個行為稱為 forking
,透過複製當前進程來執行新命令
## 當前進程啟動另一個子進程
## 子進程運行 `ps -f
ps -f
從下圖中,我們可以看到執行 ps -f
命令後 PID 為 171809
,與本來 Bash 的 PID 不同(原來 Bash 的 PID 為 169156
)
● 外部命令也被稱為 文件系統命令(存於 bash shell 之外的命令),外部命令通常放至於 bin
、/usr/bin
、sbin
、/usr/sbin
資料夾中
外部令令可以透過 which
(外部命令)、type
(內部命令)命令 找到對應位置
which ps
type ps
多 shell 關係:Shell & Sub shell
在使用 Shell 時會有父子概念(也可以想成階層概念),不同的階層會有可以相互訪問、資料是否可共享的特性,對於學習 Shell 時也是相當重要的概念
啟動子 shell:Sub shell
● 你可以透過一個已經啟動的 shell,在內部在啟動另外一個 shell,這個啟動的 shell 就是父子關係,概念圖如下
## 啟動新 shell(子)
shell
## 查看當前用戶啟動的進程
ps -f
父子 shell 的 PID 就不同 (可以透過
ps
命令查看)
上圖的父子 Shell 關係如下 (進程 ID 是 PID
,其父進程 ID 就是 PPID
)
● 可以透過
ps --forest
命令看到簡單的父子關係「圖形、階層輸出」;--forest
選項並非每個 Shell 都有,可以透過man ps
查看
進程列表:create sub shell
● 進程列表是一種 命令分組(command grouping
),透過將命令 使用括號 ()
包裹來達到讓括號內的命令運行在另一個子進程 (sub process)
A. 一般下達命令:一行中下達多個命令,預設每個外部指令都會 fork 啟動,但 不會啟動一個 sub shell 運行
一般下達命令範例如下
## 在一行中下達多個命令,**命令之間使用 `;` 區分**
ps -f ; ls ; pwd ; ps -f
下圖中,對應到上面要執行的指令,這些指令會 forking PID 14002
shell
B. 進程列表下達命令:使用括號 ()
啟動 sub shell,運行括號內的命令
進程列表下達命令令範例如下
(ps -f ; ls ; pwd ; ps -f)
下圖中,對應到範例括號內的命令,會 forking PID 14066
sub shell,也就是說指令 forking 的來源是 sub shell,而不是原來的 Shell
● 另一種命令分組是使用花括號
{}
+;
配合使用,但這種方式就 不會 啟動一個 sub shell (子 Shell),格式如下{ command; }
操控 Shell 前後景執行:jobs 使用
● 啟動背景命令
命令 | 功能 |
---|---|
fg [%n] | 切換 Shell 到前景;n 是任務編號 |
bg [%n] | 切換 Shell 到背景(ctrl + z 是掛起、休眠,兩者功能不同);n 是任務編號 |
jobs | 查看所有背景任務 |
A. 啟動 Shell 背景命令:一般 Shell 切換到背景,只需要在命令的後面 加 &
號 即可
sleep 10 &
ps -f
切換到背景後會返回一串數字,那些數字就是切換到背景運作的 Shell 的 PID
B. 查看背景 Shell:使用 jobs
命令就可以查看到任務編號,之後可以透過這個編號讓指定任務運行在前景或是背景
jobs
## 列出 PID
jobs -l
C. 切換前後景:切換 sleep 任務到背景,再切換到前景
sleep 100
## 接著按 `ctrl` + `Z` 掛起
## 切換到背景運行
bg %1
## 查任所有任務
jobs
## 切換到前景運行
fg %1
判斷 SubShell
● Ubuntu 中可以 使用 BASH_SUBSHELL
關鍵字 (變量) 來判端當前 Shell 是否是子Shell(Sub Shell)
A. 無 subshell 的狀況下會回應 0,代表頂層 Shell
echo $BASH_SUBSHELL
B. 透過進程列表創建 sub shell
($echo BASH_SUBSHELL ; sleep 100 ; )&
如下圖,我們看到使用進程列表(小擴號 ()
符號)並打印 BASH_SUBSHELL
變量,就可以看到當前的 Sub shell 階層
創建 SubShell:協程 coproc
● 除了使用進程列表之外,也可以 透過 coproc
命令將接下來要下達的命令切換到 sub shell
coproc sleep 100
ps
ps -l
● coproc
命令的另一個特點在於,可以對 sub shell 設定指定名稱,這可以讓你的 Shell 更有可讀性;格式如下
coproc <名稱> { [指令] ; }
範例如下:以下啟動一個名為 MyJob
的協程,在使用 jobs
命令查看
corproc MyJob { sleep 100 ; }
jobs -l
如下圖,我們可以看到 Sub shell 的名稱確實顯示
MyJob
Builtin Shell 應用
歷史命令 History
● history
可以查看下達 Shell 命令的歷史
history | tail
history 額外命令 | 說明 |
---|---|
!! | 執行上一個命令 |
!<命令編號> | 執行指定歷史命令 |
history -a | 對 .bash_history 寫入命令(命令不會立刻被寫入,所以必須透過 -a 命令去強至寫入) |
●
.bash_history
會儲存用戶輸入的所有命令cat .bash_history | tail
命令別名 alias
● 有時候命令太常會不方便記憶,這時我們就可以使用 alias
來對命令簡化(別名)
## 取別名
lll='ls -laF'
## 下達命令
lll
格式:<別名>=<原命令>
別名的功能只存在於當前 Shell 中,另起一個 Shell 就無法使用已經設定好的別名
● 可以透過 alias -p
查看所有可使用的別名
alias -p
更多 Linux Shell 知識
Linux 環境、服務:用戶、權限管理
● Linux 環境、服務、管理:
在這個主題中,你可以探索各種 Linux 環境、服務和管理相關的重要概念…
● 了解 Linux 組成:內核責任、GNU 工具、桌面環境 | 基礎版到發行版
在這裡,你將了解 Linux 系統的基本組成部分,包括內核、GNU 工具和桌面環境,並了解不同 Linux 發行版之間的差異
● 探索 X Window 服務與桌面環境:Linux 視窗 XWindow 服務、D-Bus 機制
這裡探討了 Linux 系統中 X Window 服務和 D-Bus 機制的工作原理,讓你深入了解桌面環境的背後運作方式
● Linux 系統管理入門:安全性、用戶管理與權限設定指南
在這個指南中,你將學習如何管理 Linux 系統,包括安全性、用戶管理和權限設定,以確保系統的安全和有效運作
● 認識身份驗證與權限管理:UNIX UID、使用者驗證與 PAM | PAM 設定
這裡介紹了 UNIX 系統中的身份驗證機制和權限管理方式,包括 UNIX UID、使用者驗證和 PAM(
Pluggable Authentication Modules
)設定
Linux Shell 相關知識
● Linux Shell 相關知識:
這個主題涵蓋了各種與 Linux Shell 相關的知識,從基礎到進階都有…
● Shell 基礎知識:包括 Shell 的基礎使用以及差異,還有變數以及計算
● 認識命令行:Shell 類型、命令差異 | Sub Shell 關係 | Builtin 命令
這裡介紹了命令行中不同類型的 Shell,以及各種 Shell 命令之間的區別和內建命令的用法
● Shell 全局及區域變數、特殊變數及環境變數 | Shell 啟動順序 | Array 變數
學習如何在 Shell 中使用全局變數、特殊變數和環境變數,以及如何設置和管理這些變數
● 探索腳本與命令:Shell 腳本的必備相關知識 | 腳本的數學運算
這裡介紹了 Shell 腳本的基本知識和常用技巧,包括如何執行腳本和進行數學運算
● Shell 結構化
● Shell 腳本程式中的條件語句和高級特性 | Shell 結構化 & 判斷
該篇文章是介紹結構化腳本的基礎以及特殊的高級技巧,轉著於腳本中的邏輯判斷
● 掌握 Bash 腳本中的迴圈與循環控制技巧 | Shell 結構化 & 循環
接著是腳本中的循環與控制的技巧,它可以讓我們在 Shell 腳本中有更多的判斷與技巧
● 探索 Shell 函數與腳本庫 | Shell 結構化 & 函數
這裡你將會學在到結構化腳本的重要技巧「函數」,它可以讓你建立可重複利用的腳本,以節省我們之後開發的時間
● Shell 掌握參數處理與用戶輸入技巧 | Shell 結構化 &輸入互動
不可互動的腳本有時候相對無趣,這篇文章有分享如何讓腳本與使用者產生交互互動,並依照使用者輸入的參數做讀取
● Shell script 進階
● Shell 命令輸入與輸出指南:掌握標準文件描述符與重定向 | 臨時文件
掌控 Shell、指令的輸出輸入是成為進階使用 CLI 之人必經的一課,透過這篇文章可以了解到輸出輸入、臨時文件等等資訊
● 探索 Linux 訊號與後台進程管理:安排定期啟動腳本 | 運行時啟動腳本
信號可以算是 Shell 腳本與 Linux 系統之間的通訊方式,透過這個文章,我們可以了解到信號與 Shell 腳本的安排時間
Linux 硬體規劃:檔案系統、分區
● Linux 硬體規劃:檔案系統、分區:
最後,這個主題涵蓋了 Linux 系統中硬體結構相關的重要概念…
● Shell 文件和目錄操作的常用命令和技巧 | 尋找檔案
這裡介紹了 Shell 中常用的文件和目錄操作命令,包括如何尋找文件和管理文件系統
● 深入探索 Linux 文件系統與硬體管理 | 分區、檔案系統、邏輯卷 | inode
學習如何管理 Linux 文件系統,包括分區、文件系統和邏輯卷等相關概念,以及文件系統中的 inode 機制
● 理解 Unix/Linux 設備偵測、建立 | 認識與使用 udevd | SCSI 與 Linux 核心
這裡介紹了 Unix/Linux 系統中的設備偵測和管理,包括如何使用 udevd 和 SCSI 相關的 Linux 核心知識