shell編程之變量,數值計算,字符比較,文件測試小記

 變量 

   變量:能儲存計算結果或能表示值抽象概念,其指向的內存空間中一段地址。    

   變量賦值:name=value
   溢出:字符超過定義內存中間大小
   變量類型:數據類型,存儲的格式,參與的運算
   編程語言:弱類型編程語言shell
   
   變量聲明:無需聲明數據類型
   不以數字開頭,字符,數字,下劃線,符號組合而成,不能使用系統保留字符(if,esle)如
   apple_sum,appleSum,user_name,userN等等ame
   
   變量賦值,用‘=’
   apple_sum=10,  appleSum=10,等等
   user_name=xiong ,userName=xiong,等等
   
   變量引用:$變量 或者 ${變量}
    echo $apple_sum  $user_name $appleSum
   
    bash變量類型    注意:數字不加引號,其他都加雙引號,在awk中正好相反,單引號表示解析,雙引號表示不解析
    1.本地變量:shell程序定義的變量,作用域僅限于當前進程本身,sshd終端開啟的進程
    [root@localhost ~]# pstree
      file://C:\Users\tom\AppData\Local\Temp\ct_tmp/1.png
     
    2.環境變量:linux定義的特殊變量,作用域為當前shell進程及其子進程,如:USER,UID,SHELL,HISTSIZE,等等
    環境變量在/etc/profile, /etc/profile.d , /etc/bashrc , 用戶目錄下.bash_profile,.bashrc等中定義
    環境變量聲明種類:    引用為:${變量},提醒中變量多是大寫,我們在寫shell盡量不要大寫
       1. export  name=value      或者    name=value;export name
       2.declare -x name=value  或者    declare -x; x=value
       file://C:\Users\tom\AppData\Local\Temp\ct_tmp/2.png  
       可以用:export,printenv,env,delclare -x查看系統環境變量,撤銷環境變量用:unset 變量
   
    3.只讀變量:
         declare -r 變量,readonly 變量  ,只讀無法重新賦值,不支持撤銷,隨shell進程終止而終止。
         file://C:\Users\tom\AppData\Local\Temp\ct_tmp/3.png
 
    4.命令變量,用反引號(`  =shift+波浪號)
         1種:name=`echo xiong`       2種:name=$(echo xiong)

    5.局部變量:作用域僅為程序的某個片(函數上下文)
    用local定義,也可不用
   
   6.參數變量:當執行的shell進程傳遞的參數
   
   7.特殊變量  shell內置的有特殊功用的變量
    $0:獲取當前執行shell腳本的文件名    
    $n:獲取當前執行shell腳本的第n個參數,n=1,2,3,4…..9,當n>9時,用${10}引用
    $#獲取當前執行shell腳本參數總個數
    $*所有參數
    $@所有參數
    file://C:\Users\tom\AppData\Local\Temp\ct_tmp/4.png
   
    $?獲取當前shell執行狀態,0表示成功,1-255表示失敗,2權限不夠,126不能執行,127未找到名利
    $$獲取當前shell執行的pid號
    $!獲取上個shell執行的pid號
   
    ${#變量名} 獲取shell變量字符長度, 返回變量字符長度  ${#xiong}, 或用  echo $變量 | wc -m,返回變量字符長度
    ${變量:位置數}從位置數后截取字符串,maoxiong=maoxiong,  echo ${maoxiong:2} 將顯示:oxiong

    ${變量:位置起始a,位置結束b}  從變量第a位置,截取到b位置:   ${maoxiong:2:2}    echo ${maoxiong} | cut -c 3-4
    ${變量#刪除字符串}刪除變量指定字符串 ,maoxiong=l am a boy;${maoxiong#l am} 結果顯示a boy
    ${變量##刪除字符串}刪除變量指定字符串 ,maoxiong=l am a boy;${maoxiong##l am a } 結果顯示boy
    ${變量%刪除字符串,從結尾處刪除}  maoxiong=l am a boy,${maoxiong%boy} ,結果顯示l am a old
    ${變量/需要替換的字符/替換的字符}  ${maoxiong/l am /you are},結果顯示為you are boy
    ${變量/#需要替換的字符/替換的字符}從開頭開始匹配  ${maoxiong/#l am /you are},結果顯示為you are boy
   
   
    變量=${man:-word}如果變量名存在,且非null,則返回變量的值。否則,返回word字符串。
    用途:如果變量未定義,則返回默認值。范例:
    ${value:-word},如果value未定義,則表達式值為word
    result=${man:-unset}如果man沒值,則result值為unset。
    file://C:\Users\tom\AppData\Local\Temp\ct_tmp/5.png
   
    變量=${man:=word}如果變量名存在且非null,則返回變量值。否則,設置這個變量值為word,并返回其值。
    用途:如果變量未定義,則設置變量為默認值,并返回默認值。
     result=${man:=set} 如果man沒有值,則將unset值賦給man,在將值賦給result
     file://C:\Users\tom\AppData\Local\Temp\ct_tmp/6.png
     
     變量=${man:?"not defined}如果變量名存在且非null,則返回變量的值。否則顯示變量名:message,并退出當前的命令或者腳本。用途:用于捕捉由于變量未定義而導致的錯誤,并退出程序
     result=${man:?word} 如變量man存在,則返回word,否則返回空
      file://C:\Users\tom\AppData\Local\Temp\ct_tmp/7.png

     變量=${value:+word}如果變量名存在且非null,則返回word,否則返回ull
     用途:測試變量是否存在。
     范例:${value:+word},如果value已經定義,則返回word(也就是真)
    file://C:\Users\tom\AppData\Local\Temp\ct_tmp/8.png
   
   
    bash特性之多shell命令執行
       命令 1;命令2;命令3;。。。。
   
    set 查看設置的變量
    set  變量名=value    設置變量
    unset 變量  撤銷變量,服務器的資源有限,在程序執行完成后,變量或者數據庫連接資源必須關閉。
   
   
  注意shell腳本是運行一個shell進程實現的

bash的配置文件
   兩類:
        profile類:為交互式登錄的shell進程提供配置     交互式如:su – root
        bashrc類:為非交互式登錄的shell進程提供配置   非交互式:1.  su root
            2.圖形界面打開的終端  3.運行的腳本等
     
      profile類:
             全局:對所有用戶都生效
             /etc/profile    /etc/profile.d/*.sh(自己自己創建shell腳本)
             用戶個人的:僅對個人有效
             ~/.bashprofile
             功用:
              1.用于定義環境變量   2.運行命令或腳本
             
      bashrc
             全局:對所有用戶都生效
               /etc/bashrc
              用戶個人的:僅對個人有效
               ~/.bashrc
               功用:
               1.定義本地變量    2.定義命令別名
               
    注意:僅管理員可修改全局配置文件
   
   
    配置文件讀取順序
    交互是登錄shell進程:
    /etc/profile–>/etc/profile.d/*–>~/.bash_profile—>~/.bashrc—>/etc/bashrc
   
     非交互式登錄shell進程:
     ~/.bahrc–>/etc/bashrc–> /etc/profile.d/*    
     
     
     命令行中定義的特性,例如變量和別人作用域為當前shell進程的生命周期
     配置文件定義的特性,只對隨后新啟動的shell進程有效
     
     讓配置文件加載方法
     (1)重新登錄系統
     (2)通過bash執行:  .配置文件  重讀配置文件
     (3)讓shell進程重讀配置文件: source 配置文件      
     
     
 
     實例:vim /etc/profile.d/xiong.sh
     內容為:echo welcome to xiong linux
     source /etc/profile.d/xiong.sh

hell腳本編程大致分兩類,根據運行方式:
編譯運行:源代碼–>編譯器轉換為程序文件,然后才能運行 tar -zxvf test.tar.gz make&&make install
解釋運行:源代碼–>運行時啟動解釋器,由解釋器邊解釋變運行

程序執行過程:
過程式: 順序執行,選擇執行,循環執行
對象式:首先定義對象,在用順序執行,選擇執行,循環執行

shell腳本規范: #為注釋符
shell腳本第一行要寫shell腳本的解釋器 #!/bin/bash 指定shell腳本的解釋器
第二行:#shell編寫者,編寫時間,聯系方式
第三行#注釋shell腳本作用等等

運行shell腳本
1.sh shell.sh 不需要執行權限 2. ./shell.sh 腳本shell.sh必須要有執行權限
3.bash shell.sh 腳本shell.sh必須要有執行權限
4.sh -x 腳本 或者bash -x 腳本 ,顯示腳本執行的過程,便于用戶調試程序bug

time命令 顯示shell程序執行的時間,用測試程序反應時間

圖片1.png


邏輯運算
true為真,用1表示。 false為假,用0表示
邏輯與: 邏輯或: 邏輯非:
1與1=1 1或1=1 !1=0
1與0=0 1或0=1 !0=1
0與1=0 0或1=1
0與0=0 0或0=0

短路運算:
短路運算: 短路或運算: 短路異或:^
第一個為0,結果必定為0 第一個為1,結果必定為1; 異或的兩個值,相同為假,不同為真
第一個為1,第二個必須要參與運算; 第一個為0,第二個必須要參與運算;


聚集命令的方法:
復合式,用分號隔開,如 date; who | wc -l
命令會一個接一個地運行
子shell:(date; who | wc -l ) >>/tmp/trace 所有的輸出都被發送給單個STDOUT和STDERR

退出狀態碼
進程使用退出狀態來報告進程的執行成功或者失敗
0 代表成功,1-255代表失敗
$? 變量保存最近的命令退出狀態
示例:

圖片3.png
自定義退出狀態碼,用于捕捉摸個進程的執行狀態
exit [n]:自定義退出狀態碼;
注意: (1)腳本中一旦遇到exit命令,腳本會立即終止;終止退出狀態取決于exit命令后面的數字
(2)如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決于腳本中執行的最后一條命令的狀態碼
示例:
圖片4.png條件測試:
判斷某需求是否滿足,需要由測試機制來實現, 專用的測試表達式需要由測試命令輔助完成測試過程;
評估布爾聲明,以便用在條件性執行中
如果條件為真,則返回0 否則則返回1
測試命令模型:
test 表達式 長格式 如: test $a -eq $b
[ 表達式 ] 短格式 如: [ $a -eq $b ]
[[ 表達式 ]] 如: [[ $a -eq $b ]]
注意:表達式前后必須有空白字符


條件性的執行操作符
根據退出狀態而定,命令可以有條件地運行
&& 代表條件性的AND THEN 實例: grep -q batman /etc/passwd || echo "no such batman"
|| 代表條件性的OR ELSE 實例:ping 10.1.0.2 -c 4 &> /dev/null && echo "10.1.0.1 is up" || echo "10.1.0.1 is down"
圖片5.png


組合測試條件
第一種方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[ -e FILE ] && [ -r FILE ]
圖片7.png
第二種方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必須使用測試命令進行; [ $USER == "root" -a -e "/etc/issue" ] && sed -n "/^#[[:space:]][[:alnum:]]\+/p" /etc/fstab



bash數值計算符(用于shell數值變量計算) 注意linux對于有小數計算時,需要用bc命令
1.基本運算符
+(加) -(減) *(乘) /(除)
%(取余或者叫做取模,如:4%3=1) **( 乘方)
圖片8.png
2.增強運算符
+= 如: a+=2等于a=a+2
-= 如: a-=2等于a=a-2
*= 如 : a*=2等于a=a*2
/= 如 : a/=2等于a=a/2
%= 如: a%/2等于a=a%2
圖片9.png
a++ 等于a,下一次則是a+1 a–等于a,下一次則是a-1
圖片10.png++a –a 記憶方法:變量再前,先輸出變量值,變量再后,就是先運算后再輸出變量制的值。

圖片11.png

3.數值運算
(1) let var=算術表達式 (2) var =$[算術表達式] (3) var =$((算術表達式))
(4)var=$(expr arg1+arg2) (5)declare -i var=數值 (6) echo '算術表達式' | bc
圖片12.png

4.數值測試:
測試格式: (1) test 表達式 (2) [ 表達式 ] 注意有空格 (3) [[ 表達式 ]] 注意空格

數值測試類型 ,執行狀態:0位真,1為假
(1) -eq 等于 [ a -eq b ] , 如果a=b,則執行狀態為真 ,否則執行狀態為假
(2) -ne 不等于 [ a -ne b ] , 如果a!=b,則執行狀態為真 ,否則執行狀態為假
(3) -gt 大于 [ a -gt b ], 如果a>b,則執行狀態為真,否則執行狀態為假
(4) -ge 大于等于 [ a -ge b ] ,如果a>=b,則執行狀態為真,否則執行狀態為假
(5) -lt 小于 [ a -lt b ] ,如果 a<b,則執行狀態為真,否則執行狀態為假
(6) -le 小于等于 [ a -le b ] ,如果a<=b,則執行狀態為真,否則為假
圖片13.png

字符串測試 注意:1.字符串用> ,<符號比較是需要加轉義字符'\',不然系統為認為是重定向等.2字符變量最好用${變量}或者"$變量"
(1) == 或 = : 測試字符串是否相等,如 a="xiong",b="xiong" ;[ $a == $b ] ,如果a等于b字符串,則執行狀態為真,否則為假
(2) > 字符串1ascii碼是否大于字符串2ascii碼 ,如 [ a > b ] ,如果a的ascii碼大于b的ascii碼,則執行狀態為真,否則為假
(3) < 字符串1ascii碼是否小于字符串2ascii碼 ,如 [ a < b ] ,如果a的ascii碼小于b的ascii碼,則執行狀態為真,否則為假
(4) != 測試字符串不相等,[ $a != $b ] ,如果a字符串不等于b,則執行狀態為真,否則為假
(5) =~ 左側字符串是否能夠被右側的pattern所匹配;注意,注意:此表達式一般用于[[ ]]中
(6) -z string : 字符串為空,則為真,否則為假
(7) -n string :字符串不空,則為真,否則為假
圖片14.png


文件測試
存在性測試
-a FILE:同-e
-e FILE: 文件存在性測試,存在為真,否則為假;
存在性及類別測試
-b FILE:是否存在且為塊設備文件;
-c FILE:是否存在且為字符設備文件;
-d FILE:是否存在且為目錄文件;
-f FILE:是否存在且為普通文件;
-h FILE 或-L FILE:存在且為符號鏈接文件;
-p FILE:是否存在且為命名管道文件;
-S FILE:是否存在且為套接字文件;

文件權限測試:
-r FILE:是否存在且可讀
-w FILE: 是否存在且可寫
-x FILE: 是否存在且可執行
-g FILE:是否存在且擁有sgid權限;
-u FILE:是否存在且擁有suid權限;
-k FILE:是否存在且擁有sticky權限;

文件屬組測試
-t fd: fd表示文件描述符是否已經打開且與某終端相關
-N FILE:文件自動上一次被讀取之后是否被修改過
-O FILE:當前有效用戶是否為文件屬主
-G FILE:當前有效用戶是否為文件屬組
文件大小測試:

文件是否為空測試
-s FILE: 是否存在且非空;

文件對比測試,也叫雙目測試:
FILE1 -ef FILE2: FILE1與FILE2是否指向同一個設備上的相同inode
FILE1 -nt FILE2: FILE1是否新于FILE2;
FILE1 -ot FILE2: FILE1是否舊于FILE2;
圖片15.png

20160810作業

一、腳本

1、編寫腳本/root/bin/,顯示當前主機系統信息,包括主機名,IPv4地址,操作系統版本,內核版本,CPU型號,內存大小,硬盤大小。

#!/bin/bash

hname=`hostname`

ipaddr=`ifconfig | sed -n '2p' | cut -d ':' -f 2 | cut -d ' '  -f 1`

osversion=`cat /etc/issue | head -1`

linuxKernel=`uname -r`

linuxCup=`lscpu | grep 'Model[^:].*' | tr -s ' '| cut -d : -f 2 | tr -s ' '`

linuxhard=`lsblk | sed -n 3p | grep  -o "\<[0-9]\+[G]\>"`

linuxme1=`free -h | grep "^[[:alpha:]].*" | tr -s ' ' | cut -d ' ' -f 1,2 | tr '\n' ' ' | cut -d ' ' -f2`

linuxme2=`free -h | grep "^[[:alpha:]].*" | tr -s ' ' | cut -d ' ' -f 1,2 | tr '\n' ' ' | cut -d ' ' -f4`

echo "主機名:$hname   主機IP:$ipaddr"

echo "系統版本:$osversion    系統內核版本:$linuxKernel"

echo "cpu型號:$linuxCup   硬盤大小:$linuxhard"

echo "內存:$linuxme1     共享內存:$linuxme2"

圖片16.png

2、編寫腳本/root/bin/backup.sh,可實現每日將/etc/目錄備份到/root/etcYYYY-mm-dd

實現自動換備份

下面shell腳本是以每分鐘備份的

#!/bin/bash

#author QQ:111111111

backTime=`date +%F-%M`

cronDir=/var/spool/cron/root

cp -r /etc/ /root/etc$backTime

#通過echo輸入crontab任務,可見自動執行創建任務,但是系統可能有警告

if [ -e $cronDir ];then

    #task=`grep "backup.sh" $cronDir | cut -d ' ' -f 7`

     task=`grep "backup" $cronDir | wc -l`

   if [ $task -eq 0 ];then

       echo "*/1 * * * * /bin/bash /root/backup.sh" >> $cronDir

       echo "backup任務已經創建。"

    else

       echo "backup已經存在"

    fi

fi

圖片17.png 

 

 

 

3、編寫腳本/root/bin/disk.sh,顯示當前硬盤分區中空間利用率最大的值

 #!/bin/bash

#author QQ:111111111

dUser=`df -h | grep "^\/" | tr -s ' ' | tr -d '%' | sort -t ' ' -k 5nr | head -n 1 |cut -d ' ' -f 5`

diskno=`df -h | grep "^\/" | tr -s ' ' | tr -d '%' | sort -t ' ' -k 5nr | head -n 1 |cut -d ' ' -f 6`

echo "$diskno: $dUser%"

 圖片18.png

 

4、編寫腳本/root/bin/links.sh,顯示正連接本主機的每個遠程主機的IPv4地址和連接數,并按連接數從大到小排序

#!/bin/bash   系統壞了,寫的shell沒了,趕作業弄個簡單版

#author QQ:111111111

netstat -tan | grep "ESTABLISHED" | awk '{print $5}'| cut -d: -f1|sort|uniq -c

圖片19.png

 

5、寫一個腳本/root/bin/sumid.sh,計算/etc/passwd文件中的

#!/bin/bash

#author QQ:111111111

var1=`cat /etc/passwd | sed -n "10p"|cut -d: -f3`

var2=`cat /etc/passwd | sed -n "20p"|cut -d: -f3`

let var3=var1+var2

echo "5、第10個用戶和第20用戶的ID之和:$var3"

 圖片20.png

 

 

6、寫一個腳本/root/bin/sumspace.sh,傳遞兩個文件路徑作為參數給腳本,計算這兩個文件中所有空白行之和

#!/bin/bash

#author QQ:111111111

file1=`grep  "^$" $1 |wc -l`

file2=`grep  "^$" $2 |wc -l`

file3=$[file1+file2]

echo "$1,$2兩個文件中所有空白行之和:$file3"

圖片21.png

 

7、寫一個腳本/root/bin/sumfile.sh,統計/etc, /var, /usr目錄中共有多少個一級子目錄和文件

#!/bin/bash

#author QQ:111111111

dirNum=`ls -l /etc/ /var/ /usr/ | cut -c1|sort | uniq -c | grep '-'| tr -s ' '| tr -d '-'

`

fileNum=`ls -l /etc/ /var/ /usr/ | cut -c1|sort | uniq -c | grep 'd'| tr -s ' '| tr -d 'd'

`

echo "文件有:$fileNum,目錄有:$dirNum"

圖片22.png 

 

8、寫一個腳本/root/bin/argsnum.sh,接受一個文件路徑作為參數;如果參數個數小于1,則提示用戶“至少應該給一個參數”,并立即退出;

如果參數個數不小于1,則顯示第一個參數所指向的文件中的空白行數

#!/bin/bash

#author:maoxiong QQ:111111111

#verson:1.0  date:2016-08

#illustrate:Comparison numbe

圖片6.png

[[ $# -lt 1 ]] && echo "輸入參數小于 1" || (echo "文件中空白行為:";grep -c  '^[[:space:]]*$' $1)

9、寫一個腳本/root/bin/,接受一個主機的IPv4地址做為參數,測試是否可連通。如果能ping通,則提示用戶“該IP地址可訪問”

;如果不可ping通,則提示用戶“該IP地址不可訪問”

#!/bin/bash

#author QQ:111111111

read -p "請輸入需要檢查的ip地址:" ipaddr

ping $ipaddr -c 2 &> /dev/null && echo "$ipaddr地址可以訪問"||echo "$ipaddr地址不可訪問"

 圖片1.png

 

 

 

 

10、判斷硬盤的每個分區空間和inode的利用率是否大于80,如果是,發郵件通知root磁盤滿

圖片2.png 

 

11、指定文件做為參數,判斷文件是否為.sh后綴,如果是,添加x權限

#!/bin/bash

#author QQ:111111111

read -p "請輸入文件:" file

echo $file | grep -o ".sh$" &> /dev/null

num=0

[ $statusNum -eq $num ] && (chmod a+x $file ;echo "$file文件存在") || echo "$file文件不存在"

圖片3.png 

 

 

13、計算1+2+3+…+100

#!/bin/bash

#author QQ:111111111

read -p "請輸入連續累加起始值:" var1

read -p "請輸入連續累加結束值:" var2

num1=$var1

num2=$var2

let num3=(num1+num2)*num2/2

echo "$num1$num2累加總合是:$num3"

圖片4.png

 

 

 

14、輸入起始值A和最后值B,A大于B,計算從A+A+1…+(B-1)+B的總和

#!/bin/bash

#author QQ:111111111

read -p "請輸入A:" var1

read -p "請輸入B:" var2

a=$var1

b=$var2

[ $a -lt $b ] && echo "A+..+B=`seq -s+ $a $b | bc`" || echo "A>B,請重新輸入"

 

圖片5.png

 

    file://C:\Users\tom\AppData\Local\Temp\ct_tmp/9.png    

原創文章,作者:maoxiong,如若轉載,請注明出處:http://www.www58058.com/34529

(0)
maoxiongmaoxiong
上一篇 2016-08-15
下一篇 2016-08-15

相關推薦

  • Linux如何快速查找需要執行的命令

    大家知道,對于熟悉命令行的用戶來說,命令行操作比圖形界面操作高效、簡潔,那么Linux是如何快速找到命令的位置呢?今天剛學了這一部分,與大家分享。         Linux將命令分為內部命令和外部命令,這是由于一些命令是常用的,需要常駐內存以減少檢索時間,所以集成在shell之…

    2017-07-15
  • AWK——文本處理三劍客

    GNU awk ·文本處理三工具:grep,sed,awk          grep,egrep,fgrep:文本過濾工具:pattern          sed:行編輯器  &nbsp…

    Linux干貨 2016-09-20
  • screen和ehco命令常用選項

    screen的用法 screen 是個外部命令,用之前需要安裝。      安裝方式之一:yum 源 安裝      yum install -y screen screen 是基于VT100/ANSI的仿真終端屏幕管理器    …

    Linux干貨 2016-07-26
  • ?入學了

    入學了

    Linux干貨 2016-10-31
  • DHCP

        動態主機設置協議(Dynamic Host Configuration Protocol,DHCP)是一個局域網的網絡協議,使用UDP協議工作,主要有兩個用途: 用于內部網絡或網絡服務供應商自動分配IP地址給用戶 用于內部網絡管理員作為對所有電腦作中央管理的手段     …

    Linux干貨 2017-07-24
  • DNS和BIND配置(第一部分)

    一、知識整理 1、最初只有七個一級域名:Top Level Domain:tld:com、edu、mil、gov、net、org、int;     一級域名分三類:組織域、國家域、反向域。最多127級域名;全球有13個根節點服務器。 2、一次完整的查詢請求經過的流程:client—hosts文件&#8212…

    Linux干貨 2016-10-17

評論列表(1條)

  • 馬哥教育
    馬哥教育 2016-08-15 09:36

    總結的很詳細,排版也很工整,態度公正,望以后的博客能按時提交。

欧美性久久久久