關於shell編程需要記憶(基礎)

關於shell編程需要記憶(基礎)

寫完shell腳本要用chmod命令加上x(執行)權限

一、shell基礎

一、通配符

文件名的擴展成爲通配,通配定義了一套使用特殊字符的規則。當輸入文件名作爲參數的命令時,可以使用特定的通配符去匹配多個文件

表1-1-1 常用的通配符

符號 含義
* 匹配任意字符的0次或多次出現
? 匹配任意零個或單個字符
[ ] 匹配字符串中所限定的任何一個字符
[^ ]或[! ] 表示反向選擇,匹配不在該字符串的任意字符
{string1,string2,…} 匹配其中一個指定的字符串

1.*(星號)

eg:匹配所有以".png"結尾的,星號可放在任意位置,匹配任意一段字符。

ls *.png

2.?(問號)

?匹配任意單個字符

?*y匹配以任意單個字符開頭以*y結尾的文件名

總而言之:?與*號不同,?只能匹配一個字符

3.[](一對方括號)

[ .]中無論有多少個字符,都只代表某一個字符。例如:[hfchg]匹配以*[ ]中**任意一個字符開頭,以任意內容結尾的。

"-"可以指定範圍例如:[a-z]匹配a-z之間任意一個字符。

4.[^]或者 [!]

表示反向選擇 例如:[^Aa]* 表示匹配不以A或者a開頭的任意文件名。

5.{}

匹配其中一個指定的字符串,

例如:{string1,string2} 表示依次以string1、string2與單個文件名進行完整匹配。

二、引號

1.’'單引號

被單引號括起來的所有內容都是普通字符,就算特殊字符也不再有特殊含義。

2.""雙引號

由雙引號括起來的字符(除$、倒引號和轉義字符""以外)均是普通字符。

​ “$”:代表引用變量的值

​ “`”:倒引號代表引用命令

[root@localhost ~]# name=xiaopeng
[root@localhost ~]# echo '$name'
$name
[root@localhost ~]# echo "$name"
xiaopeng

三、輸入、輸出重定向符

表1-3-1 常用的輸入、輸出重定向

類型 符號 作用
標準輸入重定向 command <file 將文件作爲命令的輸入
command <<分界符 從標準輸入中讀入,直到遇見分界符才停止
標準輸出重定向 command >file 以覆蓋的方式,把command正確輸出結果輸出到file文件中
command >>file 以追加的方式,把command正確輸出結果輸出到file文件中
標準錯誤輸出重定向 command 2>file 以覆蓋的方式,把command的錯誤結果輸出到file文件中
command 2>>file 以追加的方式,把command的錯誤結果輸出到file文件中

標準輸入stdin、標準輸出stdout和錯誤輸出stderr的文件描述符分別是0、1、2。(一般0和1可以不寫)

如果要把正確的結果和錯誤的結果都保存到一個文件裏,可以用 ls >file 2>&1

如果既不想把輸出結果保存到文件裏面也不想顯示在屏幕上,那麼可以把命令的所有結果重定向到 /dev/null,可以把/dev/null當成系統的垃圾箱,任何放入垃圾箱的數據都會被丟棄,無法恢復。

四、命令執行操作符

1.順序執行

使用";"連接多條命令,這些命令會依次執行,個命令之間沒有任何邏輯關係,就算有一條命令報錯後面也會繼續執行。它與寫成多行命令是等價的

2.邏輯與

如果使用"&&“連接多條命令,那麼這些命令之間就有了邏輯關係,只有第一條命令正確執行了,”&&"連接的第二條命令纔會執行。

3.邏輯或

使用"||"連接多條命令,則只有前一條命令執行錯誤,後一條命令纔會執行。

系統如何知道前一條命令是否執行呢? 那就需要用"$?"來查看前一條命令的返回值,如果是0則執行成功,如果是非0就執行錯誤。

五、小括號和大括號

小括號可以直接把若干命令括起來

大括號需要再{後面加一個空格,}前面加一個分號,大括號必須在結尾加上分號表示終止

小括號和大括號都可以將若干命令括起來(分號隔開),區別是:小括號執行組成命令時需要開啓一個子shell來執行,大括號直接在當前(父)shell中執行。

[root@localhost test]# cd 
[root@localhost ~]# (cd /etc;pwd)
/etc
[root@localhost ~]# { cd /etc;pwd;}
/etc
[root@localhost etc]# 
毋庸置疑:大括號執行以後父shell的路徑就到了etc

六、管道符、後臺命令符和註釋符

1.管道符"|"

用"|"表示,用來連接多條命令,前一條命令的輸出是後一條命令的輸入。只能處理前一條正確的輸出。

[root@localhost ~]# ls /etc |more
分頁顯示/etc目錄下的文件

2.後臺命令符"&"

當執行一些時間較長無交互的命令或者編譯時,可以在命令最後加上"&"。還可以把輸出結果重定向帶一個文件。

3.註釋符"#"

shell腳本以#開頭表示單行註釋。

在shell腳本中第一行以#!開頭後面跟shell的路徑,從而調用相應的解釋器。例如: #! /bin/bash

二、shell編程

一、變量

1.用戶自定義變量

變量名:系統變量用大寫字母,自定義變量用小寫字母(字母、下劃線開頭,由字母、數字和下劃線組成)

[root@localhost ~]# name=xiaopeng
[root@localhost ~]# echo "$name"
xiaopeng

變量賦值用"="

變量引用:變量名前面加上"$",

數組:用括號表示數組,數組裏面的值用空格分隔、

[root@localhost ~]# arr=(zhangsan lisi wangwi)
數組也可以arr[0]=zhangsan賦值

讀取數組:格式 “${數組名[下標]}”

[root@localhost ~]# echo "${arr[0]}"
zhangsan

2.系統預定義變量

表2-1-1 常用的預定義變量

預定義變量 作用
$? 上一個命令執行後的返回值(0是執行正確,非0是執行出現錯誤)
$$ 當前進程的進程號(pid)
$! 上一個後臺命令對應的進程號(pid)
$- 當前在運行shell程序的選項
$# 命令行上參數的個數
$*,$@ 命令行上實際給出的參數($*是個整體。$@是個迭代器類似數組,可以一個一個拿到)
$n n爲數字,$0是命令本身,$$1- 9 代 表 第 1 − 9 個 位 置 上 的 參 數 , 10 以 上 的 參 數 需 要 用 9代表第1-9個位置上的參數,10以上的參數需要用 91910${10}

位置參數除了運行時傳遞參數外,還可以利用set命令賦值

shift命令可以把參數往左移一位,注意不能移走$0(命令本身)。

[root@localhost test]# cat sh0
#! /bin/bash
set agr1 arg2
echo "$1"
shift
echo "$1"
#注意兩次都是打印的$1,但是結果會不同,原因是因爲shift移動了參數。
[root@localhost test]# ./sh0
agr1
arg2

3.環境變量

環境變量是系統變量(永久生效需要寫入相應的配置文件),在當前shell和所有子shell中都生效。

使用env或者export可以查看已經定義的所有環境變量

HOME:用戶家目錄的絕對路徑

PATH:shell查找命令的列表。決定了shell將到那些目錄中尋找命令或者可執行程序,當用戶輸入命令或可執行程序時,Linux在這些目錄下按順序依次搜尋。

PS1:shell的主提示符

PWD:當前工作目錄的絕對路徑

SHELL:當前使用的shell

[root@localhost ~]# echo $HOME
/root
[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/python3/bin:/root/bin
[root@localhost ~]# echo $PS1
[\u@\h \W]\$
[root@localhost ~]# echo $PWD
/root
[root@localhost ~]# echo $SHELL
/bin/bash

export聲明變量可以被子進程繼承,用法如下:

[root@localhost ~]# name=xiaopeng
[root@localhost ~]# export name
[root@localhost ~]# bash
[root@localhost ~]# echo "$name"
xiaopeng

變量的刪除: unset 變量名

[root@localhost ~]# unset name
[root@localhost ~]# echo "$name"

[root@localhost ~]# 

4.數值運算

1.使用declare聲明變量

[root@localhost ~]# declare [選項] 變量名
選項:
-:給變量設定類型屬性
+:取消變量的類型屬性
-a:將變量聲明爲數組型
-i:將變量聲明爲整數型
-r:將變量聲明爲只讀變量 (不能用+r取消,也不能修改變量)
-x:將變量聲明爲環境變量
-p:顯示變量被聲明的類型

2.使用let命令和expr命令

[root@localhost ~]# a=1
[root@localhost ~]# b=1
[root@localhost ~]# let c=$a+$b
[root@localhost ~]# echo $c
2
-----expr----運算符左右必須有空格
[root@localhost ~]# aa=1
[root@localhost ~]# bb=2
[root@localhost ~]# cc=$(expr $aa + $bb)
[root@localhost ~]# echo $cc
3

3.使用"$((算術表達式))" 加上$符號才能返回值

[root@localhost ~]# aaa=1
[root@localhost ~]# bbb=1
[root@localhost ~]# ccc=$(($aaa+$bbb))
[root@localhost ~]# echo $ccc
2

表2-1-2 常用的算術運算符

優先級 算術運算符 作用
1 =、+=、-=、*=、/=、%=、&=、|=、>>=、<<= 賦值、運算且賦值
2 || 邏輯或
3 && 邏輯與
4 | 按位或
5 ^ 按位異或
6 & 按位與
7 ==、!= 等於、不等於
8 <=、>=、<、> 小於等於、大於等於、小於、大於
9 <<、>> 按位左移、按位右移
10 +、- 加、減
11 *、/、% 乘、除、取模
12 !、~ 邏輯非、按位取反或補碼
13 -、+ 單目負、單目正

二、控制結構

1.條件測試:

條件測試有兩種形式:一種是用test命令;另一種是將一對方括號(方括號裏面頭尾加括號)將測試條件括起來。

test condition 等價於 [condition]

表2-2-1 文件測試運算符的形式及功能

參數 作用
-r 若文件存在且用戶可讀,測試條件爲真
-w 若文件存在且用戶可寫,測試條件爲真
-x 若文件存在且用戶可執行,測試條件爲真
-f 若文件存在且是普通文件,測試條件爲真
-d 若文件存在且是目錄文件,測試條件爲真
-b 若文件存在且是塊設備文件,測試條件爲真
-c 若文件存在且是字符設備文件,測試條件爲真
-s 若文件存在且文件長度大於0,測試條件爲真
-e 該文件是否存在

表2-2-2 字符串測試運算符的形式及功能

參數 作用
-z s1 若字符串s1的長度爲0,則初始條件爲真
-n s1 若字符串s1的長度大於0,則測試條件爲真
s1 = s2 若s1=s2,測試條件爲真
s1 != s2 若s1不等於s2,測試條件爲真

表2-2-3 數值測試運算符的形式及功能

需要記幾個常用的英文單詞,就很容易了。

equal:平等的 greater than:大於 less then :小於

參數 作用
n1 -eq n2 若n1等於n2,測試條件爲真
n1 -ne n2 若n1不等於n2,測試條件爲真
n1 -lt n2 若n1小於n2,測試條件爲真
n1 -le n2 若n1小於等於n2,測試條件爲真
n1 -gt n2 若n1大於n2,測試條件爲真
n1 -ge n2 若n1大於等於n2,測試條件爲真

2.if語句(判斷語句)

格式:

if [ 條件判斷式1 ]

​ then 命令1

​ elif [ 條件判斷式2 ]

​ then 命令2

​ else 命令3

fi

#! /bin/bash
echo -n "請輸入一個數字:(1-10):"
read a
if [ $a -lt 0 ] || [ $a -gt 10 ]
    then echo "錯誤的數字,程序結束!" 
        exit 2  
    elif [ $a -lt 5 ] 
    then echo "$1 小於 5"  
    else echo "$1 is 大於等於  5"  
fi

3.case語句(選擇語句)

格式:

case $變量名 in

​ “值1”) 命令;; #雙分號代表該段程序結束

​ “值2”) 命令;;

​ *) 命令;; #這裏的*號表示以上都不執行的時候執行它

esac

#! /bin/bash
echo -n "please input number:"
read a
case $a in
	"1") echo "is one";;
	"2") echo "is two";;
	"3") echo "is three";;
	"4") echo "is four";;
	"5") echo "is five";;
	*) echo "error";;
esac

4.while語句(循環語句)

格式:

while condition #條件成立執行

do

​ 命令

done

eg:輸入一個數字來求1-這個數字的和
#! /bin/bash
echo -n "please input number:"
read a
i=1
sum=0
while [ $i -le $a ]
do
	let sum+=i
	let i++
done
echo "the sum is $sum"

5.until語句(循環語句)

格式:

until condition #條件不成立執行

do

​ 命令

done

eg:求1-100的和
#! /bin/bash
sum=0
i=1
until ((i>100))
do
	((sum+=i))
	((i++))
done
echo "$sum"

6.for語句(循環語句)

語法1:

for((exp1;exp2;exp3))

do

​ 命令

done

求1-100的和
#! /bin/bash
sum=0
for ((i=1;i<=100;i++))
do
((sum+=i))
done
echo "$sum"

7.for…in語句(循環語句)

for 臨時變量 in 取值列表

求1-6的和
sum1=0
for i in 1 2 3 4 5 6
do
((sum1+=i))
done
echo "$sum1"

8.select in語句(循環語句) 適合終端交互場景

select 臨時變量 in 取值列表

do

​ 命令

done

通常和case in 一起用
#! /bin/bash
echo "Whit is your favourite OS:"
select name in "windows" "mac os" "linux" "unix" "android"
do
    case $name in
        "windows") 
            echo "windows是微軟發明的" 
            break;;     
        "mac os") 
            echo "mac是蘋果公司基於unix開發的一個圖形化界面操作系統" 
            break;;     
        “linux”) 
            echo "linux是類Unix操作系統,它開源免費" 
            break;;     
        "unix") 
            echo "unix是操作系統的開山鼻祖" 
            break;;     
        "android")
            echo "android是谷歌公司開發的,基於Linux操作系統"
            break;;     
        *)      
            echo "輸入錯誤,請重新輸入" 
    esac
done

9.continue和break

continue 用於跳出本層循環,後面跟數字表示跳出多少層

break 用於跳出整個循環,後面跟數字表示跳出多少個循環

三、shell函數

格式:

funtinue name() {

​ 命令

​ [return 返回值可有可無]

}

調用:shell函數在定義時不能指明參數,但是在調用的時候可以傳遞參數,並且傳遞聲明參數它就接收什麼參數。不限制函數函數定義的位置,可以在前面調用也可以在後面調用。

#! /bin/bash
function test(){
   
   
	echo $1
	echo $2
	echo $3
}
test 1 2 3 4
[root@localhost test]# ./function 
1
2
3

腳本實例

模擬Linux登錄

#! /bin/bash
read -p "login:" name
read -p "password:" password
if [ "$name" = "zxp" -a "$password" = "123456" ]
    then echo  "welcome to linux"
else
    echo "input is error"
fi

文件newusers給出了新用戶名單,爲新用戶創建賬號密碼。登錄名爲newusers文件裏面的名字,先檢查是否存在,若存在則提示"xx已經存在",若不存在則該創建用戶

[root@localhost test]# cat newusers 
test1
test2
test1
test3
test5
test6
test7
test2

#! /bin/bash
read -p "please input the user password:" password
for i in `cat newusers`
do
    id $i >/dev/null 2>&1
    if [ $? -eq 0 ] 
        then echo "$i用戶已存在!" 
    else
         useradd $i -p $password >/dev/null 2>&1
        if [ $? -eq 0 ] 
            then echo "$i 創建成功"
        else    
            echo "$i 創建失敗"
        fi      
    fi  
done

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章