日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux shell 高级编程,shell高级编程

發布時間:2024/8/23 linux 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux shell 高级编程,shell高级编程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

條件選擇if語句

選擇執行: 注意:if語句可嵌套

單分支

if 判斷條件;then

條件為真的分支代碼

fi

雙分支

if 判斷條件; then

條件為真的分支代碼

else條件為假的分支代碼

fi

多分支

if 判斷條件1; then

條件為真的分支代碼

elif 判斷條件2; then

條件為真的分支代碼

elif 判斷條件3; then

條件為真的分支代碼

else以上條件都為假的分支代碼

fi

逐個條件進行判斷,第一次遇為“真”條件時,執行其分支,而后結束整個if語

If示例

根據命令的退出狀態來執行命令

if ping -c1 -W2 station1 &> /dev/null; then

echo 'Station1 is UP'

elif grep "station1" ~/maintenance.txt &> /dev/null

then

echo 'Station1 is undergoing maintenance‘

else echo 'Station1 is unexpectedly DOWN!' exit 1

fi

條件判斷:case語句

case 變量引用 in

PAT1)

分支1

;;

PAT2)

分支2

;;

...*)

默認分支

;;

esac

case支持glob風格的通配符:

*: 任意長度任意字符

?: 任意單個字符

[]:指定范圍內的任意單個字符

a|b: a或b

for循環

for 變量名 in 列表;do

循環體

done

執行機制:

依次將列表中的元素賦值給“變量名”; 每次賦值后即執行一次循環體; 直到列表中的元素

耗盡,循環結束

列表生成方式:

(1) 直接給出列表

(2) 整數列表:

(a) {start..end}

(b) $(seq [start [step]] end)

(3) 返回列表的命令$(COMMAND)

(4) 使用glob,如:.sh

(5) 變量引用;$@, $

while循環

while CONDITION; do

循環體

done

CONDITION:循環控制條件;進入循環之前,先做一次判斷;每一次循環之后會再次判斷;條件

為“true”,則執行一次循環;直到條件測試狀態為“false”終止循環

因此:CONDTION一般應該有循環控制變量;而此變量的值會在循環體不斷地被修正

進入條件:CONDITION為true

退出條件:CONDITION為false

until循環

until CONDITION; do

循環體

done

進入條件: CONDITION 為false

退出條件: CONDITION 為true

循環控制語句continue

用于循環體中

continue [N]:提前結束第N層的本輪循環,而直接進入下一輪判斷;最內層為第1層

while CONDTIITON1; do

CMD1

...

if CONDITION2; then

continue

fi

CMDn

...

done

循環控制語句break

用于循環體中

break [N]:提前結束第N層循環,最內層為第1層

while CONDTIITON1; do

CMD1...if CONDITION2; then

breakfiCMDn...done

示例:doit.sh

#!/bin/bash

Name: doit.sh

Purpose: shift through command line arguments

Usage: doit.sh [args]

while [ $# -gt 0 ] # or (( $# > 0 ))

doecho $*

shiftdone

示例:shift.sh

#!/bin/bash

#step through all the positional parameters

until [ -z "$1" ]

doecho "$1"

shiftdoneecho

創建無限循環

while true; do

循環體

done

until false; do

循環體

Done

特殊用法

while循環的特殊用法(遍歷文件的每一行):

while read line; do

循環體

done < /PATH/FROM/SOMEFILE

依次讀取/PATH/FROM/SOMEFILE文件中的每一行,且將行賦值給變量line

練習

掃描/etc/passwd文件每一行,如發現GECOS字段為空,則填充用戶名和單位電話為62985600,并提示該

用戶的GECOS信息修改成功。

#!/bin/bash

while read line ;do

gecos=$(echo $line |cut -d: -f5)

if [ -z "$gecos" ];then

UserName=$(echo $line |cut -d: -f1)

usermod -c "$UserName 62985600" $UserName

echo "$UserName's gecos changed"

fi

done < /etc/passwd

編寫個腳本,會對系統中已存在的用戶進行身份判斷,若為centos7,則uid大于1000的用戶將判斷為comm user,反之判定為sys user, 若為centos6,則uid大于500的用戶判斷為comm user,反之sys user.輸出格式如下

root: sys user

……

liubei: comm user

#!/bin/bash

release=$(cat /etc/centos-release| sed -r 's/.* ([0-9]+)..*/\1/')

while read line; do

uid=$(echo $line | cut -d: -f3)

name=$(echo $line | cut -d: -f1)

if [ $release = 6 -a $uid -lt 500 ] || [ $release = 7 -a $uid -lt 1000 ]; then

echo "$name: sys user"

else

echo "$name: comm user"

fi

done < /etc/passwd

找出分區利用率大于10%的分區,顯示結果如下:

/dev/sda1 will be full : 33%

/dev/sda2 will be full : 99%

#!/bin/bash

df |grep /dev/sd |while read line;do

used=$(echo $line |tr -s " " % |cut -d% -f5)

name=$(echo $line |cut -d" " -f1)

if (( $used > 10 ));then

echo "$name will be full:$used%"

fi

done

特殊用法

雙小括號方法,即((…))格式,也可以用于算術運算

雙小括號方法也可以使bash Shell實現C語言風格的變量操作

I=10((I++))

for循環的特殊格式:

for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式))

do循環體

done控制變量初始化:僅在運行到循環代碼段時執行一次

控制變量的修正表達式:每輪循環結束會先進行控制變量修正運算,而后再做條件判斷

for ((i=1;i<=100;i++));do

let sum+=i

done

echo sum=$sum

select循環與菜單

select variable in list

do

循環體命令

done

select 循環主要用于創建菜單,按數字順序排列的菜單項將顯示在標準錯誤上,并顯示 PS3 提示符,等待用戶輸入

用戶輸入菜單列表中的某個數字,執行相應的命令

用戶輸入被保存在內置變量 REPLY 中[][][]

select 是個無限循環,因此要記住用 break 命令退出循環,或用 exit 命令終止腳本。也可以按

ctrl+c 退出循環

select 經常和 case 聯合使用

與 for 循環類似,可以省略 in list,此時使用位置參量

練習:為某餐館用Shell制作一個點菜系統。

執行腳本,會列出主菜單,如下

請問吃什么?

1) 飯

2) 面

3)餃子

4)不吃

等待用戶選擇

如選擇1,則再問,選擇完后報價

1) 炒飯

2)蓋飯

3)木桶飯

如選擇2,則再問

1)炒面

2)蓋面

3)拉面

4)拌面

如選擇3,則再問

1)豬肉大蔥

2)素三鮮

3)韭菜雞蛋

每項選擇后,最終會報價,如

木桶飯: 10元

如選擇4,則退出

#!/bin/bash

PS3="Please choose your food: "

echo "請問吃什么"

caidan() {

select menu in 飯 面 餃子 不吃;do

case $REPLY in

1) select fan in 炒飯 蓋飯 木桶飯 返回;do

case $REPLY in

1) echo "炒飯: 10";break 2;;

2) echo "蓋飯: 12";break 2;;

3) echo "木桶飯:15";break 2;;

4) caidan;;

esac

done

;;

2) select mian in 炒面 蓋面 拉面 拌面 返回;do

case $REPLY in

1) echo "炒面: 10";break 2;;

2) echo "蓋面: 12";break 2;;

3) echo "拉面:15";break 2;;

4) echo "拌面: 18";break 2;;

5) caidan;;

esac

done

;;

3) select jiaozi in 豬肉大蔥 素三鮮 韭菜雞蛋 返回;do

case $REPLY in

1) echo "豬肉大蔥: 10";break 2;;

2) echo "素三鮮: 12";break 2;;

3) echo "韭菜雞蛋:15";break 2;;

4) caidan;;

esac

done

;;

4) exit;;

esac

done

}

caidan

信號捕捉trap

trap '觸發指令' 信號

自定義進程收到系統發出的指定信號后,將執行觸發指令,而不會執行原操作

trap '' 信號

忽略信號的操作

trap '-' 信號

恢復原信號的操作

trap -p

列出自定義信號操作

trap示例

#!/bin/bash

trap 'echo “signal:SIGINT"' int

trap -p

for((i=0;i<=10;i++));do

sleep 1

echo $i

done

trap '' int

trap -p

for((i=11;i<=20;i++));do

sleep 1

echo $i

done

trap '-' int

trap -p

for((i=21;i<=30;i++));do

sleep 1

echo $i

done

函數介紹

函數function是由若干條shell命令組成的語句塊,實現代碼重用和模塊化編程

它與shell程序形式上是相似的,不同的是它不是一個單獨的進程,不能獨立運行,而是shell程序的一部分

函數和shell程序比較相似,區別在于:

1.Shell程序在子Shell中運行

2. 而Shell函數在當前Shell中運行。因此在當前Shell中,函數可以對shell中變量進行修改

定義函數

? 函數由兩部分組成:函數名和函數體 ? help function

? 語法一:

function f_name

{

...函數體...

}

? 語法二:

function f_name ()

{

...函數體...

}

? 語法三:

f_name ()

{

...函數體...

}

函數使用

? 函數的定義和使用: – 可在交互式環境下定義函數 – 可將函數放在腳本文件中作為它的一部分 – 可放在只包含函數的單獨文件中 ? 調用:函數只有被調用才會執行

調用:給定函數名

函數名出現的地方,會被自動替換為函數代碼

? 函數的生命周期:被調用時創建,返回時終止

檢查載入函數

使用set命令檢查函數是否已載入。set命令將在shell中顯示所有的載入函

示例:

set

findit=( ){

if [ $# -lt 1 ]; the

echo "usage :findit file";

return 1

fi

find / -name $1 -print

}…

刪除shell函數

現在對函數做一些改動后,需要先刪除函數,使其對shell不可用。使用unset命令完成刪除函數

命令格式為:

unset function_name

示例:

unset findit

再鍵入set命令,函數將不再顯示

環境函數

使子進程也可使用

聲明:export –f function_name

查看:export -f 或 declare -xf

函數可以接受參數:

傳遞參數給函數:調用函數時,在函數名后面以空白分隔給定參數列表即可;例如

“testfunc arg1 arg2 ...”

在函數體中當中,可使用$1, $2, ...調用這些參數;還可以使用$@, $*, $#等特殊變量

馬函數變量

變量作用域:

環境變量:當前shell和子shell有效

本地變量:只在當前shell進程有效,為執行腳本會啟動專用子shell進程;因此,本地變量

的作用范圍是當前shell腳本程序文件,包括腳本中的函數

局部變量:函數的生命周期;函數結束時變量被自動銷毀

注意:如果函數中有局部變量,如果其名稱同本地變量,使 用局部變量

在函數中定義局部變量的方法

local NAME=VALUE

函數遞歸示例

函數遞歸:

函數直接或間接調用自身

注意遞歸層數

遞歸實例:

階乘是基斯頓·卡曼于 1808 年發明的運算符號,是數學術語

一個正整數的階乘(factorial)是所有小于及等于該數的正整數的積,并且有0的階乘為1,自然數n的

階乘寫作n!

n!=1×2×3×...×n階乘亦可以遞歸方式定義:0!=1,n!=(n-1)!×n

n!=n(n-1)(n-2)...1

n(n-1)! = n(n-1)(n-2)!

#!/bin/bash

#fact() {

if [ $1 -eq 0 -o $1 -eq 1 ]; then

echo 1

else

echo $[$1*$(fact $[$1-1])]

fi

}

fact $1

×××

fork×××是一種惡意程序,它的內部是一個不斷在fork進程的無限循環,實質是一個簡單的遞歸

序。由于程序是遞歸的,如果沒有任何限制,這會導致這個簡單的程序迅速耗盡系統里面的所有資

函數實現

:(){ :|:& };:

bomb() { bomb | bomb & }; bomb

腳本實現

cat Bomb.sh

#!/bin/bash

./$0|./$0&

數組

變量:存儲單個元素的內存空間

數組:存儲多個元素的連續的內存空間,相當于多個變量的集合

數組名和索引

索引:編號從0開始,屬于數值索引

注意:索引可支持使用自定義的格式,而不僅是數值格式,即為關聯

索引,bash4.0版本之后開始支持

bash的數組支持稀疏格式(索引不連續)

聲明數組:

declare -a ARRAY_NAME

declare -A ARRAY_NAME: 關聯數組

注意:兩者不可相互轉換

數組賦值

數組元素的賦值:

(1) 一次只賦值一個元素;

ARRAY_NAME[INDEX]=VALUE

weekdays[0]="Sunday

weekdays[4]="Thursday

(2) 一次賦值全部元素:

ARRAY_NAME=("VAL1" "VAL2" "VAL3" ...)

(3) 只賦值特定元素:

ARRAY_NAME=([0]="VAL1" [3]="VAL2" ...)

(4) 交互式數組值對賦值

read

-a ARRAY

顯示所有數組:declare

-a

引用數組

引用數組元素:

${ARRAY_NAME[INDEX]}

注意:省略[INDEX]表示引用下標為

0的元素

引用數組所有元素:

${ARRAY_NAME[*]}

${ARRAY_NAME[@]}

數組的長度

(數組中元素的個數

)

${#ARRAY_NAME[*]}

${#ARRAY_NAME[@]}

刪除數組中的某元素:導致稀疏格式

unset ARRAY[INDEX]

刪除整個數組

unset ARRAY

數組數據處理

引用數組中的元素:

數組切片:${ARRAY[@]:offset:number}

offset: 要跳過的元素個數

number: 要取出的元素個數

取偏移量之后的所有元素

${ARRAY[@]:offset}

向數組中追加元素:

ARRAY[${#ARRAY[*]}]=value

關聯數組:

declare -A ARRAY_NAME ARRAY_NAME=([idx_name1]='val1'

[idx_name2]='val2‘...)

注意:關聯數組必須先聲明再調用

示例

生成10個隨機數保存于數組中,并找出其最大值和最小值

#!/bin/bash

declare -a rand

declare -i max=0

declare –i min=32767

for i in {0..9}; do

rand[$i]=$RANDOM

echo ${rand[$i]}

[ ${rand[$i]} -gt $max ] && max=${rand[$i]}

[ ${rand[$i]} -lt $min ] && min=${rand[$i]}

done

echo "Max: $max Min:$min"

示例

編寫腳本,定義一個數組,數組中的元素是/var/log目錄下所有以.log結尾的

文件;要統計其下標為偶數的文件中的行數之和

#!/bin/bash

#declare -a files

files=(/var/log/*.log)

declare -i lines=0

for i in $(seq 0 $[${#files[*]}-1]); do

if [ $[$i%2] -eq 0 ];then

let lines+=$(wc -l ${files[$i]} | cut -d' ' -f1)

fi

done

echo "Lines: $lines."

總結

以上是生活随笔為你收集整理的linux shell 高级编程,shell高级编程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。