1. 程式人生 > 其它 >Shell指令碼--菜鳥教程筆記

Shell指令碼--菜鳥教程筆記

Shell學習筆記

只針對菜鳥教程學習,後續再隨著使用完善補充

shell環境:

Shell 程式設計跟 JavaScript、php 程式設計一樣,只要有一個能編寫程式碼的文字編輯器和一個能解釋執行的指令碼直譯器就可以了。

Shell常見種類有:

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash) -- 本文記錄的是Bash的學習筆記
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)

線上編輯器:https://www.runoob.com/try/runcode.php?filename=helloworld&type=bash

編寫及執行

  1. 第一行程式碼需要告訴系統這個指令碼需要什麼直譯器來執行
#! /bin/bash
echo "hello world"
  1. 執行,以vscode執行test.sh為例(保證電腦裡有git)

shell變數

變數命名

變數名的命名須遵循如下規則:

  • 命名只能使用英文字母,數字和下劃線,首個字元不能以數字開頭。
  • 中間不能有空格,可以使用下劃線(_)。
  • 不能使用標點符號。
  • 不能使用bash裡的關鍵字(可用help命令檢視保留關鍵字)。

變數名和等號之間不能有空格

以下語句可以將檔案xx下目錄的檔名迴圈出來

for file in `ls /etc`
或
for file in $(ls /etc)

例如想列印檔案dnk下的所有檔名:

for file in `ls ./dnk`;do
    echo ${file}
done

使用變數

使用一個定義過的變數,只要在變數名前面加美元符號即可,如:

your_name="xiaohan"
echo $your_name
echo ${your_name}

花括號{}加不加都可以,但是不加的時候可能會出現和關鍵字衝突的情況,推薦寫程式碼時加上花括號。

for skill in xian nv; do
    echo "I am good at ${skill}Script"
done

以上述程式碼為例,上邊展示的是skill沒加花括號的結果,直譯器就會把$skillScript當成一個變數(其值為空),下方的結果則是我們期待的執行結果。

只讀變數

  1. 已定義的變數,可以被重新定義,如:
name="hhh"
echo ${name}
name="www"
echo ${name}

第二次賦值的時候不能寫$your_name="alibaba",使用變數的時候才加美元符($)。

  1. 使用 readonly 命令可以將變數定義為只讀變數,只讀變數的值不能被改變。
my_name="xxn"
readonly my_name
my_name="dsz"

上面的例子嘗試更改只讀變數,結果報錯:
./test.sh: line 15: my_name: readonly variable

刪除變數

使用unset可以刪除變數,但是隻讀變數不可以刪除

my_name="hhh"
unset my_name

Shell字串

定義字串

字串可以用單引號,也可以用雙引號,也可以不用引號。當字串有空格時,必須用引號

  1. 單引號
    str='this is a string'

單引號字串的限制:

  • 單引號裡的任何字元都會原樣輸出,單引號字串中的變數是無效的
  • 單引號字串中不能出現單獨一個的單引號(對單引號使用轉義符後也不行),但可成對出現,作為字串拼接使用。
  1. 雙引號
  • 雙引號裡可以有變數
  • 雙引號裡可以出現轉義字元
  • 雙引號裡可以直接打印出單引號,如果想列印雙引號需要用轉義符\
my_name="xxn"
str1="hello, I know you are \"${my_name}\""
str2="hello, I know you are '${my_name}'"
str3="hello, I know you are ${my_name}"
str4="hello, I know you are "${my_name}""
echo "str1:${str1}"
echo "str2:${str2}"
echo "str3:${str3}"
echo "str4:${str4}"

程式碼執行結果為

str1:hello, I know you are "xxn"
str2:hello, I know you are 'xxn'
str3:hello, I know you are xxn
str4:hello, I know you are xxn

拼接字串

  1. 使用單引號拼接
str='不錯'
pinjie1='今天天氣'${str}''
pinjie2='今天天氣${str}'
pinjie3='今天天氣"${str}"'
'''
結果為

今天天氣不錯
今天天氣${str}
今天天氣"${str}"

2. 使用雙引號拼接
```shell
pinjie4="今天天氣'${str}'"
pinjie5="今天天氣${str}"
pinjie6="今天天氣"${str}""

結果為

今天天氣'不錯' 
今天天氣不錯 
今天天氣不錯

在單引號內進行拼接,只可以使用成對的單引號括住定義的變數並完成拼接;直接引用和使用雙引號括住均無效,只會原樣輸出
在雙引號內進行拼接,可以使用雙引號括住變數,也可以直接使用變數;如果使用單引號括住,則單引號會被打印出來

獲取字元長度

花括號內,在字串變數名前加#即可

stt="ddwmkld12"
a=${#stt}

在使用變數的時候要加{}

提取子字串

${字串變數名:起始位置:擷取長度}

stt="ddwmkld12"
a=${stt:2:4}
echo $a

結果
wmkl

起始位置從0開始

查詢字串

#!/bin/bash
string="runoob is a great site"
# 在string字串中找r或者o,哪個先出現就輸出誰的位置
echo `expr index "$string" ro`

結果是位置偏移,從1開始,例如r的位置是1;找不到的話才輸出0

expr index STRING CHARS 命令並不是查詢 CHARS 子字串在 STRING 字串中的位置。
它只能查詢單個字元在 STRING 字串中的位置。只是 CHARS 可以指定要查詢哪幾個字元,並以第一個查詢到的字元為準。

當 STRING 字串的內容包含空格時,要用雙引號括起來,否則會報錯。

其他

字串還有很多操作,如替換、刪除等,用到再看

Shell陣列

bash只支援一維陣列,初始化時不需要定義陣列大小

定義陣列

在 Shell 中,用括號來表示陣列,陣列元素用"空格"符號分割開。定義陣列的一般形式為:

array_name=(value0 value1 value2 value3)

還可以單獨定義陣列的各個分量,可以不使用連續的下標,而且下標的範圍沒有限制。

arr[0]=50
arr[3]=30

此時輸出陣列的結果是 “50 30”,但是輸出arr[1]的話顯示空白,arr[3]才是50

讀取陣列

${陣列名[下標]}
使用 @ 或者 * 符號可以獲取陣列中的所有元素

#! /bin/bash

arr=(1 2 3 4 'sds' df)
echo ${arr[@]}

輸出的結果為

 1 2 3 4 sds df

獲取陣列的長度

和字串的方法相同

#! /bin/bash

arr=(1 2 3 4 'sds' df)
# 獲取整個陣列的長度,即陣列中有幾個元素。以下兩種都可以,結果是6
echo ${#arr[*]}
echo ${#arr[@]}
# 獲取陣列中單個元素(第5個-sds)的長度,結果為3
echo ${#arr[4]}

Shell註釋

  1. 單行註釋:以#開頭
  2. 多行註釋:
:<<xxx
註釋內容...
註釋內容...
xxx

xxx可以用任意符號代替

Shell傳遞引數

我們可以在執行 Shell 指令碼時,向指令碼傳遞引數,指令碼內獲取引數的格式為:$n。
$0代表執行的檔名稱

#!/bin/bash

echo "Shell 傳遞引數例項!";
echo "執行的檔名:$0";
echo "第一個引數為:$1";
echo "第五個引數為:$5";

傳入引數時,終端進行如下操作(上述程式碼儲存在dw.sh)

./dw.sh 1 2 3 4

結果為:

Shell 傳遞引數例項!
執行的檔名:./dw.sh
第一個引數為:1
第5個引數為:

因為只傳入了4個引數,故$5是空白
總結常用幾個引數

引數處理 說明
$0 執行的檔名
$n 第n個傳入的引數
$# 傳遞到指令碼的引數個數
$* 以一個單字串顯示所有向指令碼傳遞的引數。
$@ 與$*相同,但是使用時返回的是每個引數。

$ 與 $@ 區別:*

  • 相同點:都是引用所有引數。
  • 不同點:只有在雙引號中體現出來。假設在指令碼執行時寫了三個引數 1、2、3,,則 " * " 等價於 "1 2 3"(傳遞了一個引數),而 "@" 等價於 "1" "2" "3"(傳遞了三個引數)。
#!/bin/bash

echo "$*"
# 1 2 3 4
echo "$@"
# 1 2 3 4

for i in "$*";do
    echo '$*' $i 
done
# $* 1 2 3 4   --   相當於傳遞了“1 2 3 4”這一個引數

for j in "$@";do
    echo '$@' $j
done
# $@ 1
# $@ 2
# $@ 3
# $@ 4   ---  相當於傳遞了"1" "2" "3" "4" 四個引數

Shell運算子

  • 算數運算子
  • 關係運算符
  • 布林運算子
  • 字串運算子
  • 檔案測試運算子

算數運算子

加、減、乘、除、取餘、賦值、相等、不等 和其他語言一樣

原生bash不支援簡單的數學運算,但是可以通過其他命令來實現,例如 awk 和 expr,expr 最常用。

expr 是一款表示式計算工具,使用它能完成表示式的求值操作。語法如下

`expr $a + $b`
# 外邊的不是常用的單引號,是~下邊那個
#!/bin/bash

a=100;
b=20;
c=`expr $a + $b`
echo $c

乘法的不能直接使用,要用轉義符 /

在 MAC 中 shell 的 expr 語法是:$((表示式)),此處表示式中的 "*" 不需要轉義符號 "" 。

關係運算符

關係運算符只支援數字,不支援字串,除非字串的值是數字。

運算子 說明
-eq 兩個數是否相等
-ne 兩個數是否不相等
-gt 左邊是否大於右邊
-eq 兩個數是否相等
-eq 兩個數是否相等