曲徑通幽處,禪房花木深—-bash禪意腳本

編程基礎

程序:指令+數據

程序編程風格:

  1. 過程式:以指令為中心,數據服務于指令

  2. 對象式:以數據為中心,指令服務于數據

  3. shell程序:提供了編程能力,解釋執行

編程基本概念

編程邏輯處理方式:

  1. 順序執行

  2. 循環執行

  3. 選擇執行

shell編程:過程式、解釋執行

編程語言的基本結構:

數據存儲:變量、數組

表達式: a + b

語句:if

shell腳本基礎

shell腳本是包含一些命令或聲明,并符合一定格式的文

本文件

格式要求:首行shebang機制

  • #!/bin/bash

  • #!/usr/bin/python

  • #!/usr/bin/perl

shell腳本的用途有:

  1.  自動化常用命令

  2.  執行系統管理和故障排除

  3.  創建簡單的應用程序

  4.  處理文本或文件

創建shell腳本

第一步:使用文本編輯器來創建文本文件

 第一行必須包括shell聲明序列: #!

 #!/bin/bash

 添加注釋

注釋以#開頭

第二步:運行腳本

 給予執行權限,在命令行上指定腳本的絕對或相對路徑

 直接運行解釋器,將腳本作為解釋器程序的參數運行

shell腳本范例

1
2
3
4
5
6
7

#!/bin/bash
#author: wang
#Version: 1.0
#Description:This script displays some informationabout your
# environment
echo "Greetings. The date and time are $(date)"
echo "Your working directory is: $(pwd)"

腳本調試

bash -n /path/to/some_script

檢測腳本中的語法錯誤

bash -x /path/to/some_script

調試執行

變量

變量:命名的內存空間

數據存儲方式:

字符:

數值:整型,浮點型

變量:變量類型

作用:

1、數據存儲格式

2、參與的運算

3、表示的數據范圍

類型:

字符

數值:整型、浮點型

編程程序語言分類

強類型:定義變量時必須指定類型、參與運算必須符合類型要求;調用未聲明變量會產生錯誤,如 java,python

弱類型:無須指定類型,默認均為字符型;參與運算會自動

進行隱式類型轉換;變量無須事先定義可直接調用;如: bash 不支持浮點數

變量命名法則:

1、不能使程序中的保留字:例如if, for;

2、只能使用數字、字母及下劃線,且不能以數字開頭

3、見名知義

4、統一命名規則:駝峰命名法

bash中變量的種類

  • 根據變量的生效范圍等標準:

  • 本地變量:生效范圍為當前shell進程;對當前shell之外的其它shell進程,包括當前shell的子shell進程均無效

  • 環境變量:生效范圍為當前shell進程及其子進程

  • 局部變量:生效范圍為當前shell進程中某代碼片斷(通常指函數)

  • 位置變量: $1, $2, …來表示,用于讓腳本在腳本代碼中調用通過命令行傳遞給它的參數

  • 特殊變量: $?, $0, $*, $@, $#

本地變量

變量賦值: name=‘value’,

可以使用引用value:

(1) 可以是直接字串; name=“root”

(2) 變量引用: name=”$USER”

(3) 命令引用: name=`COMMAND`, name=$(COMMAND)

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

“”:弱引用,其中的變量引用會被替換為變量值

”:強引用,其中的變量引用不會被替換為變量值,而保持原字符串

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

刪除變量: unset name

練習

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14

#!/bin/bash
HostName=`hostname`
IP1=`ifconfig | sed -n '2p' | tr -s " " | cut -d" " -f3    `
OSversion=`lsb_release -d | tr -s " " | cut -d: -f2`
CPUinfo=`cat /proc/cpuinfo | grep 'model name'| tr -s "     " | cut -d: -f2`
KernelV=`uname -r`
MemInfo=`cat /proc/meminfo | grep 'MemTotal'`
DiskInfo=`fdisk -l | sed -n '2p' | cut -d" " -f3,4`
echo "Hostname : $HostName "
echo "IP : $IP1 "
echo "OS Version : $OSversion "
echo "CPU : $CPUinfo "
echo "Kernel : $KernelV"
echo "Disk : $DiskInfo"

201608111930001

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

201608111931001

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

201608111937001

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

 201608111959001

環境變量

變量聲明、賦值:

export name=VALUE

declare -x name=VALUE

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

顯示所有環境變量:

export

env

printenv

刪除: unset name

bash有許多內建的環境變量: PATH, SHELL, USRE,UID,

HISTSIZE, HOME, PWD, OLDPWD, HISTFILE, PS1

只讀和位置變量

只讀變量:只能引用,但不能修改和刪除

readonly name

declare -r name

位置變量:在腳本代碼中調用通過命令行傳遞給腳本的參數

  • $1, $2, …:對應第1、第2等參數, shift [n]換位置

  • $0: 命令本身

  • $*: 傳遞給腳本的所有參數,全部參數合為一個字符串(可參考為python中的字符串)

  • $@: 傳遞給腳本的所有參數,每個參數為獨立字符串(可參考為python中的列表,保持其獨立性)

  • $#: 傳遞給腳本的參數的個數

  • $@ $* 只在被雙引號包起來的時候才會有差異

示例:判斷給出的文件的行數

linecount=”$(wc -l $1| cut -d’ ‘ -f1)”

echo “$1 has $linecount lines.”

算術運算

bash中的算術運算:help let

+, -, *, /, %取模(取余) , **(乘方)

實現算術運算:

(1) let var=算術表達式

(2) var=$[算術表達式]

(3) var=$((算術表達式))

(4) var=$(expr arg1 arg2 arg3 …)

(5) declare –i var = 數值

(6) echo ‘算術表達式’ | bc

乘法符號有些場景中需要轉義, 如*

bash有內建的隨機數生成器: $RANDOM( 1-32767)

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

賦值

增強型賦值:

+=, -=, *=, /=, %=

let varOPERvalue

例如:let count+=3

自加3后自賦值

自增,自減:

let var+=1

let var++

let var-=1

let var–

export 在進行乘法運算的時候,*需要轉義

練習

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

201608112002001

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

201608112003001

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

201608112004001

邏輯運算

true, false

1, 0

與:

1 與 1 = 1

1 與 0 = 0

0 與 1 = 0

0 與 0 = 0

或:

1 或 1 = 1

1 或 0 = 1

0 或 1 = 1

0 或 0 = 0

邏輯運算

非:!

! 1 = 0

! 0 = 1

短路運算:

短路與:

第一個為0,結果必定為0;

第一個為1,第二個必須要參與運算;

短路或:

第一個為1,結果必定為1;

第一個為0,第二個必須要參與運算;

異或: ^

異或的兩個值,相同為假,不同為真

聚集命令

有兩種聚集命令的方法:

? 復合式: date; who | wc -l

命令會一個接一個地運行

? 子shell: (date; who | wc -l ) >>/tmp/trace

所有的輸出都被發送給單個STDOUT和STDERR

退出狀態

進程使用退出狀態來報告成功或失敗

? 0 代表成功, 1-255代表失敗

? $? 變量保存最近的命令退出狀態

例如:

  1. $ ping -c1 -W1 hostdown &> /dev/null

  2. $ echo $?

退出狀態碼

bash自定義退出狀態碼

exit [n]:自定義退出狀態碼;

注意:腳本中一旦遇到exit命令,腳本會立即終止;終止退出狀態取決于exit命令后面的數字

注意:如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決于腳本中執行的最后一條命令的狀態碼

條件測試

判斷某需求是否滿足,需要由測試機制來實現;

專用的測試表達式需要由測試命令輔助完成測試過程;

評估布爾聲明,以便用在條件性執行中

? 若真,則返回0

? 若假,則返回1

測試命令:

? test EXPRESSION

? [ EXPRESSION ]

? [[ EXPRESSION ]]

注意: EXPRESSION前后必須有空白字符

條件性的執行操作符

根據退出狀態而定,命令可以有條件地運行

? && 代表條件性的AND THEN

? || 代表條件性的OR ELSE

例如:

$ grep -q no_such_user /etc/passwd \

|| echo ‘No such user’

No such user

$ ping -c1 -W2 station1 &> /dev/null \

> && echo “station1 is up” \

> || (echo ‘station1 is unreachable’; exit 1)

station1 is up

test命令

長格式的例子:

$ test “$A” == “$B” && echo “Strings are equal”

$ test “$A” -eq “$B” \

&& echo “Integers are equal”

簡寫格式的例子:

$ [ “$A” == “$B” ] && echo “Strings are equal”

$ [ “$A” -eq “$B” ] && echo “Integers are equal”

bash的測試類型

數值測試:

  • -gt: 是否大于;

  • -ge: 是否大于等于;

  • -eq: 是否等于;

  • -ne: 是否不等于;

  • -lt: 是否小于;

  • -le: 是否小于等于;

bash的測試類型

字符串測試:

  • ==:是否等于;

  • >: ascii碼是否大于ascii碼

  • <: 是否小于

  • !=: 是否不等于

  • =~: 左側字符串是否能夠被右側的PATTERN所匹配

注意: 此表達式一般用于[[ ]]中;

  • -z “STRING”:字符串是否為空,空為真,不空為假

  • -n “STRING”:字符串是否不空,不空為真,空為假

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

練習

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

201608112007001

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

201608112028001

3,寫個腳本查看磁盤利用率最高的,并且判斷最大值是否大于80%,是則報警

201608112033001

文件測試

存在性測試

  • -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權限;

文件測試

文件大小測試:

  • -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

必須使用測試命令進行;

# [ -z “$HOSTNAME” -o $HOSTNAME “==\

“localhost.localdomain” ] && hostname www.magedu.com

# [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab

練習

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

201608112039001

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

201608112048001201608112102001計算1+2+3+…+100的值

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

201608112135001

原創文章,作者:M20-石俊,如若轉載,請注明出處:http://www.www58058.com/33691

(0)
M20-石俊M20-石俊
上一篇 2016-08-12 09:01
下一篇 2016-08-12 09:01

相關推薦

  • bash腳本編程class3

    bash腳本編程class3—函數定義與數組使用相關     一.函數的使用以及數組的定義   我們通過學習知道,當編輯一個shell腳本的時候,可以在這個shell腳本中調用其他的shell腳本來實現特定的功能。在實際工作環境中,用很多shell實現的功能是我們常常使用到的,如果一次一次的調用這些shell腳本會顯得非常麻煩。…

    Linux干貨 2016-08-24
  • 純文本配置還是注冊表

    我們知道Unix/Linux下的程序配置文件從來都是純文本的,你可以自由地修改和查看,他們也沒有什么什么XML之類的玩意(參看XML的這兩篇文章:一,二),這個最重要的Unix文化(參看Unix傳奇下篇)40多年來就這么沿續下來了。我很佩服Microsoft的創新能力,一會兒用INI,一會兒用注冊表,一會又是用XML,這就是Windows的編程中那“強大”的…

    Linux干貨 2016-08-15
  • Linux基礎小模塊

    1.基礎知識小塊:shell 由shell程序的自帶命令:即為內置命令(builtin) 獨立的可執行程序文件、文件名 :即為外部命令  [root@localhost~]#ls      ~用戶當前所在目錄  #:命令提示符(管理員帳號root)  $:普通用戶   &nbsp…

    Linux干貨 2016-08-05
  • 馬哥教育網絡班20期+第5周課程練習

    1、顯示/boot/grub/grub.conf中以至少一個空白字符開頭的行; grep "^[[:space:]]\+.*" /boot/grub/grub.conf   2、顯示/etc/rc.d/rc.sysinit文件中以#開頭,后面跟至少一個空白字符,而后又有至少一個非空白字符的行; grep&nb…

    Linux干貨 2016-07-12
  • 如何刪除一個目錄下的所有文件,但保留一個指定文件。附一些常用命令

    解答: 假設這個目錄是/xx/,里面有file1,file2,file3..file10   十個文件 方法如下: find /date -type f ! -name “file10″|xargs rm -f 另外還有其他的方法比如:rsync命令和bush的 extglob功能等。在此不一一列舉。 附常用命令: 文件和目…

    2017-07-15
  • 第二十六天 iptables 初識

      Iptables是位于用戶空間,是linux系統上的防火墻管理配置規則的工具,主要用于添加、刪除、管理netfilter的規則,   Netfilter是位于內核中真正的防火墻,由5個鉤子組成,也叫五個規則鏈。 Netfilter的作用:起到過濾封包,轉換與映射IP地址和端口,拆分和修改封包內容,追蹤封包等功能 Iptabl…

    Linux干貨 2016-07-02

評論列表(1條)

  • 馬哥教育
    馬哥教育 2016-08-16 15:13

    態度端正,圖文并貌題目立意很詩意哦,望后期再接再厲呢。

欧美性久久久久