shell腳本之變量類型、算數運算符、條件測試

一、bash中的變量類型

    本地變量:僅對當前shell有效,對其子shell無效

            變量賦值:name=value

                             name=$user

                             name=`Command` ,name=$(Command):這里需要注意的是“ 和 $()的意義是不同的。

                                    從下圖可以總結如下:如果將命令的執行結果賦值給一個參數時,且包含多對反引號嵌套的時候,最好外層用$()

#!/bin/bash
#
Sum=$(echo `seq $1 $2` | tr " " "+" | bc)   #################可以正確輸出
echo "$1到$2的和為:$Sum"

Sum1=`echo `seq $1 $2` | tr " " "+" | bc`   #################輸出報錯
echo "$1到$2的和為:$Sum1"
root@cenots6.8  /testdir # ./13sum.sh 1 100
1到100的和為:5050
./13sum.sh: command substitution: line 7: syntax error near unexpected token `|'
./13sum.sh: command substitution: line 7: ` | tr " " "+" | bc'
./13sum.sh: line 7: 1: command not found
1到100的和為:
root@cenots6.8  /testdir # echo `seq 1 10`
1 2 3 4 5 6 7 8 9 10
root@cenots6.8  /testdir # echo `echo `seq 1 10``
seq 1 10
root@cenots6.8  /testdir # echo $(echo `seq 1 10`)
1 2 3 4 5 6 7 8 9 10
root@cenots6.8  /testdir # echo "echo `seq 1 10`"
echo 1
2
3
4
5
6
7
8
9
10

            變量引用:$name,${name}

            顯示已定義的所有變量:set

            刪除變量:unset name

    環境變量:對當前shell及其子shell有效

            變量賦值:export name=value

                             declare -x name=value

            顯示所有環境變量:export、env、printenv

            刪除變量:unset name

            bash內置的環境變量有:PATH, SHELL, USRE,UID,HISTSIZE, HOME, PWD, OLDPWD, HISTFILE, PS1

    局部變量:對當前shell進程中某段代碼片段有效(通常指函數)

    位置變量:$1 $2……表示,用于讓腳本在腳本代碼中通過調用命令行中的傳遞的參數,1和2 分別代表第一個參數和第二個參數,shift可以替換參數

    特殊變量:$?:判斷執行結果0-255

                     $0:腳本名稱,在給腳本設置軟連接時,可以根據不同的basename來做判斷,從而進行不同的處理。

                     $*:命令行中傳遞的所有參數,且當做一個整體

                     $@:命令行傳遞的所有參數,每個參數當做一個整體

                     $#:命令行中傳遞的參數總數,與$@只在被雙引號包起來才會看出差異,可從下段腳本中看去區別

root@Centos7.2  /testdir # cat arg1.sh arg2.sh 
#!/bin/bash
#
echo 1st is $1
echo 2st is $2
echo all args are is "$*"
#!/bin/bash
#
./arg1.sh "$*"

echo ============i

./arg1.sh "$@"

echo ==============

echo $*
echo $@
root@Centos7.2  /testdir # ./arg2.sh 1 2 3
1st is 1 2 3
2st is
all args are is 1 2 3
============i
1st is 1
2st is 2
all args are is 1 2 3
==============
1 2 3
1 2 3

    只讀變量:只讀變量不能修改刪除

            變量賦值:readonly name=value 、declare -r  name=value 

    PATH變量定義位置:.bash_profile  –>  $PATH:$HOME/bin

    PATH=$PATH:$HOME/.local/bin:$HOME/bin     –.local/bin  centos7普通用戶有的隱藏的目錄,可以放寫隱藏的腳本
      寫腳本的時候可以先mkdir /home/bin 在bin目錄下寫腳本,可省去相對路徑。

    source bash.sh 也可以執行腳本:其執行過程相當于直接在當前shell進程中進行,而不是開一個子進程進行,所有腳本執行完,echo 變量,還可以查看到變量的值。(正常父進程是不能查看子進程的變量的)

    shadow 默認權限000  但是root用戶屬于超級用戶 可讀可寫,但是如果文件沒有x權限,root也不能執行

二、算數運算符

    bash中的算數運算符:+、-、*、/、%、**(平方) 注意:在使用expr的時候“*” 要轉義“\*”

        實現算數運算:

                let var=算數表達式

                var=$[算數表達式]

                var=$((算數表達式))

                var=$(expr arg1 arg2 arg3)   注意:每個參數之間要用空格隔開

            root@cenots6.8 # echo $(expr 5 \* 2 - 1)
            9

               declare -i var=數字

                echo ‘算數表達式’| bc

           隨機數生成器:echo $[RANDOM%50]:0-49之間的隨機數

                                   echo $[RANDOM%50+1]:1-50之間的隨機數

                                    $RANDOM :1-32767

三、聚合命令

        #!/bin/bash
        echo xxx;(echo zzz;exit)     ############():代表開個子shell,exit退出子shell非當前shell
        echo yyy

四、退出狀態碼

        0 代表成功, 1-255代表失敗
        $? 變量保存最近的命令退出狀態

        我們也可以指定程序退出的狀態碼,根據狀態碼的數值,來判斷工作狀態,腳本中一旦遇到exit命令,腳本會立即終止,終止,終止退出狀態取決于exit命令后面的數字,如果沒有執行exit,則取腳本最后一條命令的執行狀態結果。

五、條件測試

        測試命令:test [expression]

                         [ $a = $b ]           判斷 一對[]或兩對[[]] 都可以
                         [[ $a == $b ]]      兩個等號也可以  

                         [ -f /bin/cat -a -x /bin/cat ]    此時必須使用 一對[]  否則會報錯

        數值測試:

                        -gt:大于

                        -ge:大于等于

                        -lt:小于

                        -le:小于等于

                        -eq:等于

                        -ne:不等于

        字符串測試:

                          ==:是否相等

                          >:大于(比較ascll碼)

                          <:小于

                           !=:是否不等于

                           =~:左側字符串是否能夠被右側的PATTERN所匹配,注意: 此表達式一般用于[[ ]]中;

                           -z “string”:判斷字符串是否為空,如果為空則為真

                           -n “string”:判斷字符串是否為空,如果不為空則為真

                      注意:用于字符串比較的時候,操作數應該使用引號

        存在性測試:

                            -a file:文件存在為真,否則為假

                            -e file:同-a              

        存在性及類別測試:

                            -b FILE:是否存在且為塊設備文件            block
                            -c FILE:是否存在且為字符設備文件         char
                            -d FILE:是否存在且為目錄文件                dir
                            -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權限

        文件大小測試:

                            -s FILE: 是否存在,非空為真,否則為假

        文件是否打開:

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

        雙目測試:

                              FILE1 -ef FILE2: FILE1與FILE2是否指向同一個設備上的相同inode
                              FILE1 -nt FILE2: FILE1是否新于FILE2;
                              FILE1 -ot FILE2: FILE1是否舊于FILE2;

        組合測試條件:

                  第一種方式:
                             COMMAND1 && COMMAND2 并且
                             COMMAND1 || COMMAND2 或者
                             ! COMMAND 非
                                        如: [ -e FILE ] && [ -r FILE ]
                  第二種方式:
                            EXPRESSION1 -a EXPRESSION2 并且
                            EXPRESSION1 -o EXPRESSION2 或者
                            ! EXPRESSION

        

一、作業:

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

#!/bin/bash
#編寫腳本/root/bin/systeminfo.sh,顯示當前主機系統信息,包括主機名,IPv4地址,操作系統版本,內核版本,CPU型號,內存大小,硬盤大小。
IPaddr=`ifconfig | sed -n '2p'| sed 's@.*inet addr:@@g' | sed 's@Bc.*@@'`
SysVersion=`cat /etc/redhat-release`
CPU=`sed -n "5p" /proc/cpuinfo |cut -d: -f2|tr -d " "`
MemInfo=`sed -n '1p' /proc/meminfo |cut -d: -f2|tr -d " "`
FdiskInfo=`fdisk -l |sed -n '2p' | grep -o ".*GB"| sed -r "s@Dis.*: @@"`
echo "HostName: `hostname`"
echo "Ipaddress: $IPaddr"
echo "SysVersion: $SysVersion"
echo "KernelVersion: `uname -r`"
echo "CPU: $CPU"
echo "MemInfo: $MemInfo"
echo "FdiskInfo: $FdiskInfo"

unset IPaddr 
unset SysVersion
unset CPU
unset MemInfo
unset FdiskInfo
root@cenots6.8  /testdir # ./systeminfo.sh 
HostName: cenots6.8
Ipaddress: 10.1.249.49  
SysVersion: CentOS release 6.8 (Final)
KernelVersion: 2.6.32-642.el6.x86_64
CPU: Intel(R)Core(TM)i5-5200UCPU@2.20GHz
MemInfo: 1004136kB
FdiskInfo: 128.8 GB

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

#!/bin/bash
#編寫腳本/root/bin/backup.sh,可實現每日將/etc/目錄備份到/root/etcYYYY-mm-dd中
dirName="/root/etc`date +%F`"
cp -a /etc $dirName && echo " 備份成功"
root@cenots6.8  /testdir # ls -d ~/etc* ; du -sh ~/etc*
/root/etc2016-08-12
41M    /root/etc2016-08-12

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

#!/bin/bash
#編寫腳本/root/bin/disk.sh,顯示當前硬盤分區中空間利用率最大的值
Use=`df | tr -s " "|cut -d" " -f5|sed -n '1!p'|sort -n|tr -d % |tail -1`
[ $Use -gt 10 ] && wall disk will be full!
unset Use
root@cenots6.8  /testdir # ./checkdisk.sh 

Broadcast message from root@cenots6.8 (pts/1) (Fri Aug 12 10:38:52 2016):

disk will be full

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

#!/bin/bash
#編寫腳本/root/bin/links.sh,顯示正連接本主機的每個遠程主機的IPv4地址和連接數,并按連接數從大到小排序
linCount=`netstat -t | grep "tcp" | tr -s " " | cut -d" " -f5 | sed "s@:.*@@" | sort -n | uniq -c`
echo -e “鏈接數    IP地址”
echo -e "$linCount"
root@cenots6.8  /testdir # ./links.sh 
“鏈接數 IP地址”
      2 10.1.250.130

5、寫一個腳本/root/bin/sumid.sh,計算/etc/passwd文件中的第10個用戶和第20用戶的ID之和

#!/bin/bash
#寫一個腳本/root/bin/sumid.sh,計算/etc/passwd文件中的第10個用戶和第20用戶的ID之和
UserId10="`sed -n '10p' /etc/passwd | cut -d: -f3`"
UserId20="`sed -n '20p' /etc/passwd | cut -d: -f3`"
SumId=$[UserId10+UserId20]
echo "第10個用戶和第20用戶的ID之和為:$SumId"

unset UserId10
unset UserId20
unset SumId
root@cenots6.8  /testdir # ./sumid.sh 
第10個用戶和第20用戶的ID之和為:180

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

#!/bin/bash
#寫一個腳本/root/bin/sumspace.sh,傳遞兩個文件路徑作為參數給腳本,計算這兩個文件中所有空白行之和
File1="`grep "^$" $1 | wc -l`"
File2="`grep "^$" $2 | wc -l`"
SpaceSum=$[File1+File2]
echo "兩個文件中所有空白行之和: $SpaceSum "

unset File1
unset File2
unset SpaceSum
root@cenots6.8  /testdir # ./sumspace.sh /etc/profile /etc/fstab 
兩個文件中所有空白行之和: 12

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

#!/bin/bash
#寫一個腳本/root/bin/sumfile.sh,統計/etc, /var, /usr目錄中共有多少個一級子目錄和文件#
EtcNum="`ls /etc/ | wc -l`"
VarNum="`ls /var/ | wc -l`"
UsrNum="`ls /usr/ | wc -l`"
SumFile=$[$EtcNum+$VarNum+$UsrNum]
echo "The Sumfile: $SumFile"

unset EtcNum
unset VarNum
unset UsrNum
unset SumFile
root@cenots6.8  /testdir # ./sumfile.sh 
The Sumfile: 287

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

#!/bin/bash
#寫一個腳本/root/bin/argsnum.sh,接受一個文件路徑作為參數;如果參數個數小于1,則提示用戶“至少應該給一個參數”,并立即退出;如果參數個數不小于1,則顯示第一個參
數所指向的文件中的空白行數
[[ $# -lt 1 ]] && echo "至少應該給一個參數" ||  echo "SpaceNum: `grep "^$" $1 | wc -l`"
root@cenots6.8  /testdir # ./argsnum.sh 
至少應該給一個參數
root@cenots6.8  /testdir # ./argsnum.sh /etc/profile
SpaceNum: 11

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

#!/bin/bash
#
ping -c1 -W2 $1 &> /dev/null && echo "該IP地址可訪問" || echo "該IP地址不可訪問"
root@cenots6.8  /testdir # ./hostping.sh 10.1.249.48
該IP地址可訪問
root@cenots6.8  /testdir # ./hostping.sh 10.1.249.4
該IP地址不可訪問

10、chmod -rw /tmp/file1,編寫腳本/root/bin/per.sh,判斷當前用戶對/tmp/fiile1文件是否不可讀且不可寫

#!/bin/bash
#
[ -r /testdir/file1 -a -w /testdir/file1 ] && echo "`whoami` 可讀可寫" || echo "`whoami`非可讀可寫"
root@cenots6.8  /testdir # ./per.sh 
root 可讀可寫
tom@cenots6.8  /testdir # ./per.sh
tom非可讀可寫

11、編寫腳本/root/bin/nologin.sh和login.sh,實現禁止和充許普通用戶登錄系統。

#!/bin/bash
#編寫腳本/root/bin/nologin.sh和login.sh,實現禁止和充許普通用戶登錄系統。
[ ! -f /etc/nologin ] && echo "普通用戶已不可以登陸系統" && touch /etc/nologin

[ -f /etc/nologin ] && echo "普通用戶已可以登陸系統" && rm -rf  /etc/nologin
root@cenots6.8  /testdir # ./login.sh  #########################禁止普通用戶登陸
普通用戶已不可以登陸系統
[c:\~]$ ssh tom@10.1.249.49

Connecting to 10.1.249.49:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.

Connection closed by foreign host.

Disconnected from remote host(10.1.249.49:22) at 12:09:27.

Type `help' to learn how to use Xshell prompt.
root@cenots6.8  /testdir # ./login.sh ##########################允許普通用戶登陸
普通用戶已可以登陸系統
[c:\~]$ ssh tom@10.1.249.49

Connecting to 10.1.249.49:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.

tom@cenots6.8  ~ #

12、寫一個腳本/root/bin/hostping.sh,接受一個主機的IPv4地址做為參數,先判斷是否合格IP,否,提示IP格式不合法并退出,是,測試是否可連通。如果能ping通,則提示用戶“該IP地址可訪問”;如果不可ping通,則提示用戶“該IP地址不可訪問”

#!/bin/bash
#
echo "$1" | grep -E -qo  '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])' && ( ping -c1 -W2 $1 &> /dev/null && echo "該IP地址可以訪問" || echo "該IP地址不可以訪問") || echo "該IP地址不合法";exit 1
root@cenots6.8  /testdir # ./hostping.sh
該IP地址不合法
root@cenots6.8  /testdir # ./hostping.sh 10.1.249.49
該IP地址可以訪問
root@cenots6.8  /testdir # ./hostping.sh 192.192.192.192
該IP地址不可以訪問

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

#!/bin/bash
#
Num=`echo {1..100} | tr " " "+" | bc`
echo "$1到$2的和為:$Num"
root@cenots6.8  /testdir # ./13sum.sh 
到的和為:5050
#!/bin/bash
#
Sum=$(echo `seq $1 $2` | tr " " "+" | bc)
echo "$1到$2的和為:$Sum"
root@cenots6.8  /testdir # ./13sum.sh 1 100
1到100的和為:5050

14、計算從腳本第一參數A開始,到第二個參數B的所有數字的總和,判斷B是否大于A,否提示錯誤并退出,是則計算之

#!/bin/bash
#計算從腳本第一參數A開始,到第二個參數B的所有數字的總和,判斷B是否大于A,否提示錯誤并退出,是則計算之
Sum=$(echo `seq $1 $100` | tr " " "+" | bc)
[ $1 -lt $2 ] && echo $1到$2的和為:$Sum || echo "$1 不能大于 $2" ;exit 1
root@cenots6.8  /testdir # ./14sum.sh 1 100
1到100的和為:5050
root@cenots6.8  /testdir # ./14sum.sh 100 1
100 不能大于 1

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

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

相關推薦

  • Jumpserver 3.0 全新改版 更輕、更快、更便捷

               Jumpserver Wiki                       &…

    系統運維 2016-01-05
  • 制作epel源

    在linux的使用過程中,ISO鏡像的rpm包并不是十分的齊全。這個時候就需要去epel源去下載安裝rpm包安裝。這里簡單的描述下epel源的配置方法。僅供參考。 1.關閉SELinuxsed -i.bak ‘s/SELINUX=enforcing/SELINUX=permissive/’ /etc/selinux/config se…

    2017-12-18
  • HTTP協議

    HTTP協議   HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用于從萬維網(WWW:World Wide Web )服務器傳輸超文本到本地瀏覽器的傳送協議。HTTP是一個基于TCP/IP通信協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)。HTTP協議工作于客戶端-服務端架構之上。瀏覽器作為HT…

    Linux干貨 2017-02-15
  • bash的基礎特性

    1、Bash的命令補全      使用tab鍵可以實現命令補全或者路徑補全 2、Bash的命令行展開      使用~,可以展開為用戶的家目錄;             例如#cd ~ 表示切換目錄到當前用戶家目錄中   &nbs…

    Linux干貨 2016-11-02
  • Apache Httpd負載均衡Tomcat并實現Session Sticky和Session Cluster

    Apache Httpd負載均衡Tomcat并實現Session Sticky和Session Cluster 前言 實驗拓撲 實驗步驟 安裝配置tomcat 安裝配置Apache Httpd并測試 實現session sticky 實現Session Cluster 總結 前言 上篇文章我們介紹如何構建一個LANMT平臺并搭建一個jspxcms, 這次我們…

    2016-04-22
  • linux系統文件的元數據

    linux系統文件的元數據 什么是元數據 文件的數據分兩種: 一種元數據,既屬性數據:metadata 一種就是數據本身:data 如何查看元數據: stat stat命令用于顯示文件的狀態信息 [root@localhost ~]# stat /tmp/mylinux File: ‘/tmp/mylinux’ Size: 143 Blocks: 0 IO …

    Linux干貨 2018-03-11

評論列表(1條)

  • 馬哥教育
    馬哥教育 2016-08-16 14:21

    層次分明,邏輯清晰,詳細具體,再接再厲哦

欧美性久久久久