腳本 & 命令:命令集、多命令
使用多個不同命令時,只需在每個命令之間使用 ;
隔開即可
who ; date
多命令:複合執行 &&
● 一般來說我們在使用多命令時會使用 ;
符號,稍加詳細地說這個符號會執行多個命令,而不判斷其中哪個命令是否成功
● 如果要讓命令依照順序執行,並且判斷其中是否有錯誤,可以使用 &&
符號;從以下範例就可以清楚地看出其差異
# 有錯誤仍往下執行
echo "Start" ; nocmd ; echo "End"
# 有錯誤就不往下執行
echo "Start" && nocmd && echo "End"
創建 shell 腳本:命令集
● 腳本 & 命令
腳本就是透過多個命令組成(所以上面這個多命令也是一個簡單的腳本)
命令一次不要下達超過 255 個
● shell 腳本其實就是將指令寫入某個文件中;首先 1. 需要指定該腳本文件由哪個 Shell 分析 (#!<Shell 路徑>
)、2. 寫入需要的指令
#!/bin/bash
# first bash script
date
who
指令可以使用換行分開、也可以使用
;
分開
● 腳本不可運行?
預設創建出來的文件會因為 umask(002),將文件權限設定為 664,也就是預設該文件是不可執行,這時 只需要透過
chmod
改變即可chmod u+x firstShell.sh
● 想讓腳本在任何目錄中都可以被呼叫到?
A. 將腳本目錄加入 PATH
B. 使用絕對路徑去呼叫腳本
● 腳本中如果要輸出訊息給使用者看,可以使用 echo
命令
#!/bin/bash
# first bash script
date
who
## -n 代表不換行
echo -n "Hello script~"
echo "Yo"
● 運行腳本
./firstScript.sh
腳本內使用變量
● 要在腳本中使用變量有兩種,1. 環境變數變量($<環境變量名>
)、2. 腳本臨時變量(也稱為用戶變量)
變量有分大小寫
● 引用變量時都是使用 $
符號,如果不使用這個符號,那變量就只是普通的字串,而不是真正的數值(透過 $
符號才可引出數值)
環境變量
● 腳本中使用環境變量
● 查詢環境變量,可以使用
set
、printenv
、env
... 等等命令
#!/bin/bash
# use variable in script
# echo 雙引號中使用 $ 符號就可以引用變數
#
# 如果你要使用 $ 符號,請配合跳脫符號 `\`
echo "User: $USER"
echo "Uid: $UID"
echo "Hime: $HOME"
● 運行腳本
chmod u+x
./variable.sh
腳本臨時變量
● 腳本臨時變量:脫離腳本後就不復存在
#!/bin/bash
# local variable for script
# 臨時變量
hello=1111
world=2222
echo "hello=$hello, world=$world"
● 運行腳本
chmod u+x
./local_variable.sh
腳本內執行命令
Shell 腳本中可以從命令 A 的輸出提取訊息,並賦予變量,這種腳本內執行命令的方式也稱之為「命令替換」
● 命令替換符號中的命令,會由 sub shell 執行?
這不一定,是否由 sub shell 執行這取決於你使用的命令,如果是內建命令則不啟用 sub shell 執行,外部命令則啟用 sub shell 執行
# cd 就是內建命令 type cd
可使用
type
命令來分別內建、外部命令
反引號 & 引用格式
● 以下有兩種方法可以把可以將命令輸出給變量
A. 反引號 `<命令>`:bash 會執行反引號內的命令(這種使用方式較為傳統)
B. 引用格式 $(<命令>):bash 會執行 $() 內的命令
#!/bin/bash
# catch the command output
# 反引號
catch_1=`date`
echo "catch the output by \` \`: $catch_1 "
# 引用格式
catch_2=$(date)
echo "catch the output by \$( ): $catch_2 "
● 執行命令
chmod u+x catch_cmd.sh
./catch_cmd.sh
退出腳本
退出腳本對於 Shell 來說很重要,Shell 的判斷式就是判斷 Shell 退出時的退出碼來決定該命令是否執行成功!
每個指令都會執行過後都會返回 退出狀態碼(exist status),來告知該腳本執行的結果
● 狀態碼範圍為 0 ~ 255 的整數
查看退出碼:$?
● Linux 提供一個特殊符號來 $?
來保存上一個命令的退出狀態碼 (只會保留上一次的結果),其狀態碼也代表了不同意義
A. 成功:退出碼為 0
date && echo "\$? $?"
從上面實驗我們可以知道指令執行成功後返回的結果是 0,也就是 數字 0 代表命令執行成功
B. 失敗:退出碼非 0 都是失敗,並沒有特殊規則可循
# 無用命令
abc
echo "\$? $?"
● 失敗退出碼雖然沒有規則但有 慣例,我們可以按照以下慣例去判斷(但並非決定)
退出狀態碼 慣例意義 0 成功 1 一般未知錯誤 2 不合適的 shell 命令 126 該命令不可執行 127 找不定該命令 128 無效的退出參數 128+x 與 Linux 信號 x 相關的嚴重錯誤 130 透過 Ctrl+C 終止命令 255 正常範圍之外的退出狀態碼 以下分別執行了錯誤指令(127) & 不可執行的命令(126)
退出腳本:exit 命令
● 我們在退出腳本時可以使用 exit
命令,該指令可以指定退出碼
#!/bin/bash
var1=10
var2=20
result=$(bc<< EOF
a=$var1 * $var2
b=$var2 / $var1
a+b
EOF
)
echo "result=($result)"
exit 27
格式:exit <退出碼>
● 當給予退出碼大於 255 則會取 256 餘數
假設給 exit 555,那最終我們讀取退出碼時就會是 43 (555 % 256 的結果)
重定向:輸入/輸出
● 如果要將命令的結果輸出到另一個位置(有可能是另一個命令中、或是輸出到檔案),那就需要重定向
重定向類型 | 符號 | 說明 |
---|---|---|
輸出重定向(覆蓋) | > | 將命令結果輸出到另一個位置;如果輸出到文件,則會覆蓋文件內容 |
輸出重定向(追加) | >> | 同上,不過不會覆蓋文件內容,而是追加文件內容 |
輸入重定向 | < | 將文件內容輸入到命令中 |
輸入重定向(條件型) | << | 可一直輸入內容直到指定符號,才完整輸入到命令中 |
輸出重定向
● 輸出重定向:
以下範例示範輸出的重定向,使用重定向的追加符號(>>
)、覆蓋符號(>
)
# 輸出命令 (覆蓋)
./catch_cmd.sh > redirection_output_1.txt
cat redirection_output_1.txt
# 追加輸出
./catch_cmd.sh >> redirection_output_1.txt
cat redirection_output_1.txt
輸入重定向
● 輸入重定向:使用 wc
指令測試輸入重定向
wc 輸出格式「文本行數 詞數 字節數」
wc
命令是 words counts,用來判斷文件字數
以下範例將 redirection_output_1.txt
檔案輸入到 wc
指令中
# 將文本內容輸入給 wc 命令
wc < redirection_output_1.txt
● 條件型 輸入重定向:
另外一個有趣的用法是作為「輸入的結尾條件」,當判斷到輸入的內容為指定內容,那就停止輸入,範例如下…
# 你可以一直輸入文字,直到輸入 'YoYo' 為止
# 才會將文字匯入 wc 命令運行
wc << YoYo
管道 Pipe
如果要將某個命令作為下一個命令的輸入,這時就可以使用管道技巧;管道格式如下
# 管道用法
<命令 A> | <需要 A 命令結果的命令>
管道的使用範例
● Unix 管道的使用範例
# 首先列出所有已安裝的軟體
# 將安裝軟體的結果輸出給 sort 使用(sort <上一個結果>)
# 最後將 sort 結果在輸出給 head (head <上一個結果>)
apt list --installed | sort | head
● 命令的執行順序?
兩個命令會同時執行,由系統內部將命令進行串接(就像是物件導向的 Link 鏈式設計)
腳本的數學運算
對於任何程式語言來說操作數字都是基礎能力,對於 Shell 當然也是,不過 Shell 對於數字的處理較為麻煩
Bourne shell:expr
命令
● Bourne shell 提供了一個特別的命令 expr
來處理數學表達式,其可以處理的內容如下表(提及幾個常用的)
操作符 | 描述 | 成立後返回 | 不成立返回 |
---|---|---|---|
ARG1 | ARG2 | ARG1 非 0 也不是 NULL 就返回 ARG1,否則返回 ARG2 | ARG1 | ARG2 |
ARG1 & ARG2 | ARG1 和 ARG2 都非 0 也不是 NULL,則返回 ARG1 | ARG1 | 0 |
ARG1 < ARG2 | 小於 | 1 | 0 |
ARG1 <= ARG2 | 小於等於 | 1 | 0 |
ARG1 = ARG2 | 等於 | 1 | 0 |
ARG1 != ARG2 | 不等於 | 1 | 0 |
ARG1 >= ARG2 | 大於等於 | 1 | 0 |
ARG1 > ARG2 | 大於 | 1 | 0 |
ARG1 + ARG2 | 加法 | ARG1+ARG2 | - |
ARG1 - ARG2 | 減法 | ARG1+ARG2 | - |
ARG1 * ARG2 | 乘法 | ARG1+ARG2 | - |
ARG1 / ARG2 | 除法 | ARG1+ARG2 | - |
ARG1 % ARG2 | 取模 | ARG1%ARG2 | - |
● expr 符號的衝突
expr 符號很多會與原生 Shell 使用的符號衝突,當符號衝突時可以使用跳脫符號來避免(
\
)# Error `*` 符號衝突 expr 5 * 2 # 使用跳脫字元 expr 5 \* 2
● 以下範例 使用 expr
命令來運算數學
#!/bin/bash
# test expr command
var1=10
var2=20
# 記得命令替換是使用 `$()` 符號
# 內部執行 expr 命令時仍須關心是否有符號衝突的問題
result=$(expr $var1 \* $var2)
echo "$var1 * $var2 = $result"
● 執行命令
chmod u+x expr_test.sh
./expr_test.sh
Bash shell:$[ ]
符號
● Bash shell 運算中有一種更方便的方式:
使用 $[ ]
符號,使用這個符號就不用擔心符號衝突的問題
#!/bin/bash
# test $[] command
var1=10
var2=20
result=$[$var1 * $var2]
echo "$var1 * $var2 = $result"
● 執行命令
chmod u+x expr_test2.sh
./expr_test2.sh
:::warning
● $[ ]
符號只能計算整數,不能計算浮點數
浮點數計算:bc 命令
● 透過 bc
命令就可以計算浮點數,首先 bc
命令的基礎用法如下 (不用腳本的狀況)
輸入
quit
就可以退出計算
bc
命令還可以儲存暫時變量
:::info
● bc 內建變量 scale
的設置
透過設定 scale 就可以控制計算結果輸出的小數點位數
● 在腳本中使用 bc
命令,以下有兩種方式
A. 基本使用
#!/bin/bash
var1=100.1
var2=222.3
# scale 設定最多輸出 4 個小數點
result=$(echo "scale=4; $var1 * $var2" | bc)
echo "result=($result)"
● 運行腳本
chmod u+x float_cal.sh
./float_cal.sh
B. 配合重指向:如果要較長的計算,那就可以使用「輸入重指向」
#!/bin/bash
var1=1.12
var2=3.1415926
var3=102
result=$( bc << END
scale=5
a1=($var1 * $var2)
a2=(($var2 + $var1) * $var3)
a1 + b2
END
)
echo "final result=($result)"
● 重新導向的內部局部變數是不可以使用的,否則會出錯(以上面範例來說
a1
,a2
就不能拿來計算)
更多 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 核心知識