跟馬哥學linux (lesson 7)Bash腳本基礎知識

1、Linux程序分類:node

1.守護進程(Daemon):開機自動啓動linux

常見linux後臺守護進程列舉:c++

amd:NFS守侯進程算法

apmd:高級電源治理shell

Arpwatch:記錄日誌並構建一個在LAN接口上看到的以太網地址和ip地址對數據庫數據庫

Autofs:自動安裝治理進程automount,與NFS相關,依靠於NIS編程

crond:linux下的計劃任務bash

Dhcpd:啓動一個DHCP(動態IP地址分配)服務器服務器

Httpd:WEB服務器網絡

Inetd:支持多種網絡服務的核心守候程序

Lpd:打印服務器

named:DNS服務器

netfs:安裝NFS、Samba和NetWare網絡文件系統

portmap:RPC portmap治理器,與inetd相似,它治理基於RPC服務的鏈接

routed:路由守候進程,使用動態RIP路由選擇協議

sendmail:郵件服務器sendmail

smb:Samba文件共享/打印服務

snmpd:本地簡單網絡治理候進程

squid:激活代理服務器squid

syslog:一個讓系統引導時起動syslog和klogd系統日誌守候進程的腳本

xfs:X Window字型服務器,爲本地和遠程X服務器提供字型集

xntpd:網絡時間服務器

ypbind:爲NIS(網絡信息系統)客戶機激活ypbind服務進程

yppasswdd:NIS口令服務器

ypserv:NIS主服務器

 

2.交互式進程:shell應用程序

shell程序組成部分:腳本或程序的源文件

 

二.linux編程的基本知識

1.編譯執行

處理過程分爲:預處理—>編譯—>彙編—>連接等4個過程 c或c++均採用此種方式

以C語言示例程序Hello World爲例演示過程

a.預編譯

p_w_picpath

b.編譯

p_w_picpath

c.彙編

p_w_picpath

d.連接

p_w_picpath

2.解釋執行:由解釋器全程參與運行過程,每次讀取一行,運行一行

Python:編程庫

            程序控制結構,調用編程庫完成程序編寫

            庫文件:功能模塊,在編程中調用:經過其API

例:使用Pthon打印hello world

p_w_picpath

p_w_picpath

Bash:編程

            程序控制結構,調用機器上命令程序文件運行程序編寫

            外部命令:個應用程序提供

例:使用bash shell打印hello world

p_w_picpath

p_w_picpath

3.兩種編程思想

其一爲:過程式編程,以指令爲中心,設計算法,數據服務於算法

其二爲:對象式編程,以數據爲中心,設計數據結構(類)程序服務於數據結構

 

三.詳解Bash編程

1.變量相關知識

變量的定義:可變的量,命令的內存空間

變量的生效範圍:

                本地變量:當前shell

                環境變量:當前shell及其自進程

                局部變量:某個函數執行過程

變量類型:

               數值,字符:

               數值:整數,浮點

               字符:ASCII

               位置參數變量:在腳本中傳遞給腳本的參數

               特殊變量:$? 打印上一個命令執行結果0爲正確執行1-255爲錯誤執行

                                  $* 參數個數

                                  $@ 參數個數

                                  $$ ppid

                                  $# 參數總數

                                  $1-n 第一到第n個參數

變量類型的做用:

               存儲空間,運算,存儲格式

語言對變量類型的支持力度:

              強類型:變量類型嚴格區分 C,Java等

              弱類型:變量類型不嚴格區分,默認存儲機制爲字符 Bash,Python等

bash的變量使用特色:弱類型,無需事先聲明

定義本地變量:

name=value

name:變量名

=:賦值符號

value:變量值

變量名:只能包含數字、字符和下劃線,且不能以數字開頭

引用變量 :${name} $name

引用類型:

弱引用:使用「」其內部的變量會替換爲變量值

p_w_picpath

強引用:使用'' 其內部不會發生變量替換

p_w_picpath

命令引用:`COMMAND`,$(COMMAND)引用變量執行的結果

p_w_picpath

聲明一個變量:declare -i name[=value]或let name=value

p_w_picpath

變量的生命週期:

            建立:執行name=value

            銷燬:自動銷燬 shell進程結束 手動銷燬unset name

p_w_picpath

環境變量定義:被導出的本地變量,生效範圍爲本shell及其派生的子shell

export name[=value]

declare -x name[=value]

查看全部環境變量:env printenv export set

銷燬:unset name

p_w_picpath

 

2.bash編程基礎

腳本:文本文件

        運行腳本:運行一個bash進程,此進程負責從腳本文件中讀取一個邏輯,由bash負責解釋和運行此邏輯

啓動腳本:

        (1)#bash /PATH/TO/SCRIPT_FILE

        (2)一個執行權限 #./PATH/TO/SCRIPT_FILE

格式:第一行:定格shebang

p_w_picpath

bash經常使用選項:-n檢查腳本語法

                            -x調試執行腳本

                            -v顯示詳細信息

p_w_picpath

3.bash測試邏輯

測試方式:

根據運行的命令的狀態結果

測試表達式:test [EXPR1] [EXRP2] 或 [ EXPR1 測試表達式 EXPR2 ]

 

整數測試:

$A -gt $B 是否大於

p_w_picpath錯誤返回

$A -ge $B  是否大於小於

p_w_picpath錯誤返回

$A -lt $B 是否小於

p_w_picpath正確返回

$A -le $B 是否小於等於

$A -eq $B 是否等於

$A -ne $B 是否不等於

 

字符串測試:

注:字符串比較字母排列的前後順序,字符串比較須要使用` `

「$A」> "$B":是否大於

p_w_picpath正確返回

「$A」<「$B」:是否小於

p_w_picpath

「$A」==「$B」 是否等於

「$B」!=「$B」是否不等於

p_w_picpath

-z "$A" 是否爲空,空則真

p_w_picpath

-n "$A" 是否爲非空,非空爲真

 

文件測試:測試文件的存在性以及屬性

-e|-a $file 是否存在,存在爲真

測試/etc/fstab是否存在

p_w_picpath

-f $file 文件是否存在且爲普通文件

測試/etc/fstab是否爲普通文件

p_w_picpath

-d $file 文件是否存在且爲目錄

測試/etc是否爲目錄

p_w_picpath

-h|-L $file 文件是否存在且爲符號鏈接文件

測試/dev/cdrom是否爲符號連接

p_w_picpath

-b $file 塊設備文件

測試/dev/sda1是否爲塊設備文件

p_w_picpath

-S $file socket文件

p_w_picpath

權限測試:

-r $file 存在且具備可讀權限

測試/etc/passwd是否有可讀權限

p_w_picpath

-w $file 存在且有可寫權限

測試/etc/passwd是否有可讀權限

p_w_picpath

-x $file 存在且有可執行權限

p_w_picpath

-u $file 存在且有suid權限

p_w_picpath

-g $file 存在且有sgid權限

-o $file 存在且有sticky權限

-O $file 當前用戶是否爲指定文件的屬主

-G $file 當前用戶是否爲指定文件的屬主

 

雙目操做符比較

$file1 -nt $file2 file1是否比file2新

p_w_picpath

$file1 -ot $file2 file1是否比file2舊

 

$file1 -ef $file2 file1和file2是否指向同一個inode便是否爲硬連接

p_w_picpathhello爲hello.sh的硬連接指向同一個inode

p_w_picpath

3.bash條件判斷和循環語句

bash條件判斷(選擇執行)

語法格式:

if CONDITION;then if-true-分支;fi

p_w_picpath

if CONDITION;then if-true-分支 ;else if-else分支 ;fi

p_w_picpath

! CONDITION:取反

 

腳本參數(位置參數變量)

# ./script.sh /etc/fstab

$0 腳本自己

$1 第一個參數

$2 第二個參數

$n 第n個參數

p_w_picpath

shift能夠對參數進行偏移

p_w_picpath

p_w_picpath

使用read命令能夠實現交互式程序編寫

經常使用參數:-p 給出提示語句 -t 超時時間

p_w_picpath

循環語句:

for 循環列表;do 執行的操做;done

p_w_picpath

while 循環列表;do 執行的操做;done

p_w_picpath

p_w_picpath

until 循環列表;do 執行的操做;done

 

循環:將循環體代碼執行0,1或屢次

進入條件:進入循環的條件

退出條件:循環終止的條件

for VAR in LIST;do 循環體;done

LIST:是由一個或多個空格或換行符分隔開的字符串組組成

 

組合測試條件:

條件間邏輯運算:

與:多個條件同時知足

或:多個條件知足其一便可

非:對指定的條件取反

表達式組合:

與:[ CONDITION1 -a CONDITION2 ]

p_w_picpath

或:[ CONDITION1 -o CONDITION2 ]

p_w_picpath

非:[ ! CONDITION ]

p_w_picpath

 

命令組合:

與:COMMAND1 && COMMAND2  其中&&爲短路與操做,即當COMMAND1正確執行後COMMAND2纔會被執行

p_w_picpath

或:COMMAND1 || COMMAND2 其中&&爲短路或操做,即當COMMAND1沒有被正確執行後COMMAND2纔會被執行

p_w_picpath

與:! COMMAND

 

case語句:

簡潔版的多分支if語句

使用場景:判斷某變量的值是否爲多分支的一種時使用

語法:

case $VAR in

PATTERN1)

分支1

;;

PATTERN2)

分支2

;;

PATTERNn)

分支n

;;

esac

輸入一個數,10和20均顯示false,50爲true

p_w_picpath

 

2、課堂練習

一、寫一個腳本:若是某路徑不存在,則將其建立爲目錄;不然顯示其存在,並顯示內容類型;(不要懷疑,就是這麼簡單)

二、寫一個腳本,完成以下功能;判斷給定的兩個數值,孰大孰小;給定數值的方法:腳本參數,命令交互;(使用read,依然如此簡單)

三、求100之內全部奇數之和(至少用3種方法。是的這是咱們的做業^_^)

四、寫一個腳本實現以下功能:

(1) 傳遞兩個文本文件路徑給腳本;

(2) 顯示兩個文件中空白行數較多的文件及其空白行的個數;

(3) 顯示兩個文件中總行數較多的文件及其總行數;

五、寫一個腳本

(1) 提示用戶輸入一個字符串;

(2) 判斷:

若是輸入的是quit,則退出腳本;

不然,則顯示其輸入的字符串內容;

六、寫一個腳本,打印2^n表;n等於一個用戶輸入的值;(很差意思,我調皮了)

七、寫一個腳本,寫這麼幾個函數:函數一、實現給定的兩個數值的之和;函數二、取給定兩個數值的最大公約數;函數三、取給定兩個數值的最小公倍數;關於函數的選定、兩個數值的大小都將經過交互式輸入來提供。

解答:

1.

#!/bin/bash    
aaa="/etc/aaa"   
if [ ! -e "$aaa" ]     
  then mkdir $aaa && echo "create successful."     
  else echo "$aaa has exist." && ls -l $aaa     
fi

p_w_picpath

2.

#!/bin/bash    
if [ $# -ne 2 ];then echo "Plz enter 2 numbers.";fi     
if [ $1 -gt $2 ];then echo $1 ">" $2     
  elif [ $1 -lt $2 ];then echo $1 "<" $2     
  elif [ $1 -eq $2 ];then echo $1 "=" $2     
  else echo "unkonw."     
fi

p_w_picpath

3.

方法1、

#!/bin/bash    
declare -i i     
declare -i sum=0     
for i in {1..100}     
  do if [ $(($i%2)) -ne 0 ];then sum=$i+$sum;fi     
done     
echo $sum

p_w_picpath

方法2、

#!/bin/bash    
declare -i aaa     
declare -i sum=0     
for aaa in `seq 1 2 100`     
  do sum=$aaa+$sum     
done     
echo $sum

p_w_picpath

方法3、

#!/bin/bash    
declare -i i     
declare -i sum=0     
declare -i oddsum=0     
declare -i evensum=0     
for i in {1..100}     
  do sum=$i+$sum     
    if [ $(($i%2)) -eq 0 ];then oddsum=$oddsum+$i;fi && evensum=$sum-$oddsum     
done     
echo $evensum

p_w_picpath

4.

#!/bin/bash    
if [ $# -ne 2 ]     
  then echo "Plz enter 2 files"     
  else sumline1=`cat $1|wc -l` sumline2=`cat $2|wc -l` blank1=`grep '^$' $1|wc -l` blank2=`grep '^$' $2|wc -l`     
    if [ $blank1 -gt $blank2 ];then echo "more blank line is $1 $blank1 lines"     
       else echo "more blank line is $2 $blank2 lines"     
    fi     
    if [ $sumline1 -gt $sumline2 ];then echo "more line is $1 $sumline1 lines"     
       else echo "more line is $2 $sumline2 lines"     
    fi     
fi

p_w_picpath

5.

#!/bin/bash    
while true     
do     
read -t 5 -p "Plz enter someting. " aaa     
  if [ $aaa == "quit" ];then exit     
    else echo $aaa     
  fi     
done

p_w_picpath

6.注:(次題目參考了@謝俊同窗,並略加修改。)

[object Object]
#!/bin/bash
#
read -t 5 -p "please enter a number: " x
[ -z $x ]&&echo "Errot:please enter a number!"
count=2
for i in $(seq 0 $x);do
    if [ $i -eq 0 ];then
       echo -e $((2**$i))
    elif [ $i -eq 1 ];then
       echo -e $((2**$i))
    elif [ $i -gt 1 ];then
    count+=x2              # 字符的自加,感謝「天真的小同志」的指導
    echo $count=$[2**$i]
    else echo "Error:please enter a number!"
    fi
done
7.
#!/bin/bash
#
sum() {
read -p "Plz enter two number. " args1 args2
echo sum=$((args1+args2))
}

gcd() { #先求出其中任意兩個數的最大公約數,再求這個最大公約數與第三個數的最大公約數,依次求下去,直到最後一個數爲止。
read -p "Plz enter two number. " a b
c=$((a%b)) #對a,b進行取模運算
while [ "$c" -ne 0 ];do #當a,b的模不等於0時
gcd=$c #對gcd進行第一次賦值,gcd等於a,b的模
a=$b  #把上一次b的至賦給a
b=$c  #把上一次c的值賦給b
c=$((a%b)) #再一次進行取模,一直進行循環直到c的值爲0
done
echo "gcd=$gcd"
}

lcm() { #最小公倍數爲兩個數的伺機除以最大公約數
read -p "Plz enter two number. " a b
c=$((a%b))
pro=$((a*b))
while [ "$c" -ne 0 ];do
gcd=$c
a=$b
b=$c
c=$((a%b))
done
echo "lcm=$((pro/gcd))"
}
case $1 in
sum)
sum
;;
gcd)
gcd
;;
lcm)
lcm
;;
*)
echo "Plz Usage `bashname`{sum|gcd|lcm}"
;;
esac

wKioL1X6PpjAPWkKAAErfdk7sx8471.jpg

wKiom1X6PGCwF_gjAAFBrjBcsys436.jpg

wKioL1X6PpjxW9MSAAD8pDlmoJ0046.jpg

相關文章
相關標籤/搜索