shell程式設計基礎

2022-08-04 06:04:18

shell名詞解釋

  • Kernel:Linux核心,主要是為了和硬體打交道
  • shell: 是一個命令列直譯器,接收使用者命令/應用程式,然後呼叫作業系統核心。還是一個程式設計語言。
  • 檢視當前shell直譯器和系統支援的shell直譯器(我這裡用的是centos7的映象)
  • shell的兩大主流
    1. sh:
      Bourne shell(sh),Solaris,hpux預設shell
      Bourne again shell(bash),linux系統預設shell
    2. bash
      C shell(csh)
      tc shell(tcsh)

在Linux系統中,sh是bash的一個軟連結(軟連結又叫符號連結,這個檔案包含了另一個檔案的路徑名。可以是任意檔案或目錄,可以連結不同檔案系統的檔案。)

#!宣告
告訴系統其後路徑所指定的程式是解釋此指令碼檔案的shell程式,也就是指定shell直譯器bash,路徑是/bin/bash

shell指令碼的執行

  1. 輸入指令碼的絕對路徑或者相對路徑

shell指令碼檔案的字尾是sh,這裡使用vim建立並編輯內容後使用絕對路徑執行helloword這個指令碼沒有許可權,更改許可權後使用絕對路徑和相對路徑都可以執行

  1. bash或sh+指令碼的絕對路徑或相對路徑
    注意:當指令碼沒有x(執行)許可權時,root和檔案所屬使用者通過這個方式可以正常執行

我這裡已經將許可權改成了不可執行,但是通過這個方式依然可以執行

  1. source+指令碼的絕對路徑或相對路徑

檢視正在執行的程序
ps -ef

三種執行方式的區別
第一種和第二種在用bash直譯器執行指令碼時,會先生成一個新的bash,在新的bash中執行
第三種就是在一個bash中執行的,在後面的區域性變數中也會體現

shell變數

  • 定義變數時,變數名不加$符號
  • 命名只能用英文字母,數位和下劃線,首個字元不能以數位開頭
  • 中間不能有空格,不能使用標點符號
  • 不能使用bash裡面的關鍵字(可以用help命令檢視)

變數的型別

  • 區域性變數
    區域性變數在指令碼或命令中定義,僅僅只在當前shell範例中有效,其他shell啟動的程式不能存取區域性變數
  • 環境變數
    所有的程式,包括shell啟動的程式,都能存取環境變數,有些程式需要環境變數來保證其正常執行

我在shell中定義了一個區域性變數name,使用sh呼叫指令碼,在指令碼中列印這個區域性變數沒有顯示,但是在指令碼中定義的區域性變數age卻列印出來了,後面我使用export (作用是可以將當前程序的變數傳遞給子程序去使用)將區域性變數name變成了環境變數,這時就可以列印了,造成這種情況的原因是因為前面sh呼叫指令碼時,會先生成一個新的bash,在新的bash裡面執行,此時我們在外面用命令定義的區域性變數和bash執行的指令碼不在同一個bash內,自然是列印不出來的,在當前shell是可以列印的。
[root@master01 scripts]# echo "${name}"
bfy

刪除變數
unset

shell的字串
字串可以用單引號,也可以用雙引號,也可以不用引號
注意:

  1. 單引號裡的任何字元都會原樣輸出,單引號字串中的變數是無效的
  2. 單引號字串中不能出現單獨一個單引號,可以成對出現,作為字串的拼接使用
  3. 雙引號裡可以有變數
  4. 雙引號裡可以出現跳脫字元

這裡的:<<!

  !
  是多行註釋,使用時不侷限於感嘆號,EOF也可以,甚至是你自定義的字元
  在雙引號中使用換行符時,需要加上-e

字串長度


這裡的#是取字串長度,因為定義變數的時候不能取標點符號,所以沒有列印
1:4是指從1開始,去四個字元,字串是從0開始的

shell陣列
bash支援一維陣列,不支援多維陣列,並且沒有限定陣列的大小
陣列的下標從0開始,格式上與Java陣列有所不同

shell引數傳遞
執行shell指令碼時,向指令碼傳遞引數,指令碼內獲得引數的格式為:$n n代表一個數位


這裡前9個引數都正常,從第10個開始就發生了變化,原因是$10被預設成了$1拼接上一個0,也就是110。解決辦法是給10用大括號括起來。

shell運運算元
運運算元的分類
算術運運算元

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

(1)\(((運算式))或\)[運算式]
(2)expr + , - , \*, /, % 加,減,乘,除,取餘
注意:expr運運算元間要有空格
程式碼:

關係運算子

= 字串比較
-lt 小於(less than) -le 小於等於(less equal)
-eq 等於(equal) -gt 大於(greater than)
-ge 大於等於(greater equal) -ne 不等於(Not equal)

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

布林運運算元

字串運運算元

(shell的echo指令用於字串的輸出,詳情可以看我上一篇部落格)

shell流程控制
if判斷
if [ 條件判斷式 ];then
程式
fi
或者
if [ 條件判斷式 ]
then
程式
elif[ 條件判斷式 ]
then
程式
fi
注意事項:
(1)[ 條件判斷式 ],中括號和條件判斷式之間必須有空格
(2)if後要有空格

read 讀取控制檯輸入
read(選項)(引數)
選項:
-p:指定讀取值時的提示符;
-t:指定讀取值時等待的時間(秒)。
引數
變數:指定讀取值的變數名

case語句
case $變數名 in
「值1」)
如果變數的值等於值1,則執行程式1
;;
「值2」)
如果變數的值等於值2,則執行程式2
;;
…省略其他分支…

如果變數的值都不是以上的值,則執行此程式
;;
esac
注意事項:
1)case行尾必須為單詞「in」,每一個模式匹配必須以右括號「)」結束。
2)雙分號「;;」表示命令序列結束,相當於java中的break。
3)最後的「
)」表示預設模式,相當於java中的default。

for迴圈

for (( 初始值;迴圈控制條件;變數變化 ))
do
程式碼
done

while迴圈
while [ 條件判斷式 ]
do
程式
done

break命令終止執行後面的所有迴圈
continue命令不會跳出所有迴圈,僅僅跳出當前迴圈

shell函數

linux shell 可以使用者定義函數,然後在shell指令碼中可以隨便呼叫。

可以帶function fun() 定義,也可以直接fun() 定義,不帶任何引數。

引數返回,可以顯示加:return 返回,如果不加,將以最後一條命令執行結果,作為返回值。return後跟數值n(0-255)