Reference
https://blog.csdn.net/w918589859/article/details/108752592
https://www.w3cschool.cn/linux/linux-Shell.html

一、Shell 簡介

  • 什麼是 Shell?
    Shell 是一個用 C 語言編寫的程式,它是使用者使用 Linux 的橋樑。Shell 既是一種命令語言,又是一種程式設計語言。
    Shell 是指一種應用程式,這個應用程式提供了一個界面,使用者通過這個界面訪問作業系統核心(kernel)的服務。
  • 為什麼要學習和使用 Shell?
    Shell 屬於內建的腳本,程序開發的效率非常高,依賴於功能強大的命令可以迅速的完成開發任務(批次處理)。
  • Shell 腳本(Shell script)
    是一種為 Shell 編寫的腳本程式。業界所說的 Shell 通常都是指 Shell 腳本。

二、 Shell 入門

1. Shell 環境

  • Shell 編程需要能編寫程式碼的文本編輯器和一個能解釋執行的腳本解釋器
  • 在 linux 中有很多類型的 Shell,不同的 Shell 具備不同的功能,Shell 還決定了腳本中函數的語法。
  • Bash 是 Linux 中默認的 Shell。一般情況下,人們不區分 Bourne Shell 和 Bourne Again Shell,所以 #!/bin/sh 也可以被替換成 #!/bin/bash
  • Linux 的 Shell 種類眾多,不同的 Shell 都有自己的特點以及用途,常見的有:
    • Bourne Shell (/usr/bin/sh/bin/sh)
    • Bourne Again Shell (/bin/bash)
    • C Shell (/usr/bin/csh)
    • K Shell (/usr/bin/ksh)
    • Shell for Root(sbin/sh)
    • ……

2. Bash 常用快捷鏈

快捷鏈功能
Ctrl+A把游標移動到命令行開頭。
Ctrl+E把游標移動到命令行結尾。
Ctrl+C強制終止當前的命令。
Ctrl+L清除螢幕,等於 clear 指令。
Ctrl+U清除並剪下當前命令。
Ctrl+K刪除並剪下游標以後的命令。
Ctrl+Y貼上。
Ctrl+R在歷史命令中搜索,按下 Ctrl+R 之後,就會出現搜索界面,只要輸入搜索內容,就會從歷史命令中搜索。
Ctrl+D退出當前終端機。
Ctrl+Z暫停,並放入後台。
Ctrl+S暫停螢幕輸出。
Ctrl+Q恢復螢幕輸出。

3. 輸入與輸出 I/O

  • linux 的標準輸入與輸出

    設備設備名文件描述符類型
    鍵盤/dev/stdin0標準輸入
    顯示器/dev/stdout1標準輸出
    顯示器/dev/stderr2標準錯誤輸出
  • 輸入重定向
    輸入重定向:是指不使用系統提供的標準輸入界面,而進行重新的指定。換言之,輸入重定向就是不使用標準輸入界面輸入文件,而是使用指定的文件作為標準輸入設備。
    (簡言之就是用 < 來修改標準輸入設備)

    類型語法功能
    標準輸入command < file命令把文件中的內容作為標準輸入設備。
    標識限定輸入command << tag命令讀取標準輸入中的內容,直到遇到標識符號為止。
    輸入輸出重定向(同時使用)command < file1 > file2命令把文件1中的內容作為標準輸入,把文件2作為標準輸出。
  • 輸出重定向
    輸出重定向:將輸出的文件訊息寫入到指定文件。
    &表示全部文件,文件不管對錯,1表示標準輸出文件、2表示標準錯誤輸出。

    類型語法功能
    標註輸出重定向command > file以覆蓋方式,把命令的正確輸出內容輸出到指定的文件或設備中
    標註輸出重定向command >> file以追加方式,把命令的正確輸出內容輸出到指定的文件或設備中
    標準錯誤輸出重重定向err_command 2> file以覆蓋方式,把命令的錯誤輸出輸出到指定的文件或設備當中
    標準錯誤輸出重重定向err_command 2>> file以追加方式,把令命的錯誤輸出輸出到指定的文件或設備中
    正確輸出和錯誤輸出同時保存command > file > 2>&1以覆蓋的方式,把正確輸出和錯誤輸出都保存到同一個文件
    正確輸出和錯誤輸出同時保存command >> file 2>&1以追加方式,把正確輸出和錯誤輸出都保存到同一個文件
    正確輸出和錯誤輸出同時保存command &> file以覆蓋的方式,把正確輸出和錯誤輸出都保存到同一個文件
    正確輸出和錯誤輸出同時保存command &>> file以追加方式,把正確輸出和錯誤輸出都保存到同一個文件
    正確輸出和錯誤輸出同時保存command >> file1 2>> file2把正確的輸出追加到文件1,把錯誤的輸出追加到文件2中。
  • /dev/null
    若希望執行某個命令,但又不希望在螢幕上顯示輸出結果,那麼可以將輸出重定向到 /dev/null 中。

[root@localhost ~]$ command > dev/null

4. 多命令順序執行

多命令執行符作用格式
;命令1;命令2多個命令順序執行,命令之間沒有任何邏輯關係。
&&命令1&&命令2當命令1正確執行,命令2才會執行;當命令1執行不正確,則命令2不會執行。
||命令1||命令2當命令1正確執行,命令2不執行;當命令1執行不正確,則命令2才會執行。

5. Shell 腳本(Shell script)

撰寫腳本

[root@localhost ~]$ vim test.sh
#!/bin/bash
echo "hello world"
  • #! 是一個約定的標記,它告訴系統這個腳本需要什麼解釋器來執行,即使用哪一種 Shell。
  • echo 命令用於向 Console 輸出文本。
  • file.sh .sh是linux下 bash Shell 的預設副檔名

執行方法

  1. 增加執行權限
[root@localhost ~]$ chmod u+x test.sh       // 對所有user增加對當前目錄下的test.sh文件的執行權限
[root@localhost ~]$ ./test.sh
  • chmod: change the permissions mode of a file
  • u: user
  • +x: 增加執行權限
  1. 通過 bash 調用執行腳本
[root@localhost ~]$ bash test.sh

三、 Shell 變數

1. 變數的命名規則

  • 首個字元必須為英文字母 (a-z,A-Z)
  • 中間不能有空格,可以用底線(_)取代。
  • 不能使用標點符號。
  • 不能使用關鍵字(可用 help 查看保留關鍵字)。
  • 環境變數習慣大寫,便於區分。

調用變數示例

[root@localhost ~]$ test=123
[root@localhost ~]$ test="$test"456
[root@localhost ~]$ echo $test
123456
[root@localhost ~]$ test=${test}789
[root@localhost ~]$ echo $test
123456789

Shell 中的特殊符號

符號作用
''在單引號中所有字元都是普通字元,照原樣輸出。
""在雙引號中只有 $ 與 ` 和 \ 是有特殊含義,分別是調用變數引用命令轉義
``在反引號中的內容是系統命令,在 Bash 中會先執行,與 () 作用一樣,但不推薦使用。
$()和反引號作用相同,用來引用系統命令。
()用於一串命令執行時,() 中的命令會在子 Shell 中運行。
{}用於一串命令執行時,{} 中的命令會在當前 Shell 中執行。也可以用於變數變形與替換。
[]用於變數的測試。
#用於注釋。
$用於調用變數的值。
\用於轉義。

單引號與雙引號示例

[root@localhost ~]$ name=rain
[root@localhost ~]$ echo '$name'
$name
[root@localhost ~]$ echo "$name"
rain
[root@localhost ~]$ echo `date`
2023年 1月17日 週二 21時23分45秒 CST
[root@localhost ~]$ echo '`date`'
`date`
[root@localhost ~]$ echo "`date`"
2023年 1月17日 週二 21時24分00秒 CST

反引號示例

[root@localhost ~]$ echo ls
ls
[root@localhost ~]$ echo `ls`
words.txt
[root@localhost ~]$ echo $(date)
2023年 1月17日 週二 21時28分42秒 CST

2. 變數的分類

變數分類名稱作用內容
自定義變數自定義自定義自定義
使用自定義環境變數自定義自定義自定義
系統環境變數預定預定自定義
位置參數變數預定自定義自定義
預定義變數預定自定義自定義

2.1. 自定義變數:

  • 最常見的變數,由使用者自由定義變數名稱與值。
    • 使用 $ 調用變數。
    • 使用 set [選項] 設定
    • -u:調用未宣告變數時會報錯(預設未無提示)
    • -x:在命令執行之前,會把命令先輸出一次
    • +<參數>:取消某個曾啟動過的參數
    • set:查詢系統中所有的變量,包含自定義變數與環境變數
    • unset 變數名稱:刪除變數

2.2. 環境變數:

  • 主要保存和系統操作環境相關的數據,比如當前登錄的使用者名稱,使用者的根目錄、命令的提示符等。一般對系統起作用的環境變數名稱是系統預定好的。
    • 使用 export 宣告的變數即是環境變數
    • 使用 env 查看環境變數

2.3. 位置參數變數:

  • 用來向腳本當中傳遞參數或數據的,變數名稱不能自定義,變數作用是固定的。
    • $n:n 為數字,$0表示當前 Shell 腳本程式的名稱,10以上需加大括號。
    • $*:代表命令行中所有參數,$把所有參數看成一個整體。
    • $@:代表命令行中所有參數,不過$把每個參數區分對待。
    • $#:代表命令行中所有參數的個數

腳本示例1

#!/bin/sh
echo "shell's name: $0"
echo "shell's first argument: $1"
echo "shell's second argument: $2"
[root@localhost ~]$ bash test.sh 1 2
shell's name: test.sh
shell's first argument: 1
shell's second arguemnt: 2

腳本示例2

#!/bin/sh
for i in "$*"
  do
    echo "The parameter is: $i"
  done
x=1
for y in "$@"
  do
    echo "The parameter$x is: $y"
    x=$(( $x +1 ))
  done
[root@localhost ~]$ bash par.sh 1 2 3 4 5 6
The parameter is: 1 2 3 4 5 6
The parameter1 is: 1
The parameter2 is: 2
The parameter3 is: 3
The parameter4 is: 4
The parameter5 is: 5
The parameter6 is: 6

2.4. 預定義變數:

  • 是Bash中已經定義好的變數,變數名稱不能自定義,變數作用也是固定的。
    預定義變數作用
    $?最後一次執行的命令的返回狀態。如果這個變數的值為 0,表示上一個命令正確執行;如果這個變數的值非 0(具體為哪個數,由命令自己決定),則表示上一個命令執行不正確。
    $$當前程式的程式號(PID)
    $!後台運行的最後一個程式的程式號(PID)

腳本示例1

[root@localhost ~]$ ls
count.sh hello.sh parameter.sh
[root@localhost ~]$ echo $?
0
[root@localhost ~]$ ls install.log
ls: install.log: No such file or directory
[root@localhost ~]$ echo $?
1