shell腳本基礎

編程基礎

v程序:指令+數據

v程序編程風格:

過程式:以指令為中心,數據服務于指令(適合小型程序)

對象式:以數據為中心,指令服務于數據(適合大型程序)

vshell程序:提供了編程能力,解釋執行

程序的執行方式

v計算機:運行二進制指令;

v編程語言:

低級:匯編

高級:

編譯:高級語言–>編譯器–>目標代碼

java,C#

解釋:高級語言–>解釋器–>機器代碼

shell, perl, python

編程基本概念

v編程邏輯處理方式:

順序執行

循環執行

選擇執行

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

編程語言的基本結構:

數據存儲:變量、數組

表達式: a + b

語句:if

Shell腳本

shell腳本基礎

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

格式要求:首行shebang機制

#!/bin/bash(.sh后綴結尾)

#!/usr/bin/python(.py后綴結尾)

#!/usr/bin/perl(.pl后綴結尾)

shell腳本的用途有:

自動化常用命令

執行系統管理和故障排除

創建簡單的應用程序

處理文本或文件

創建shell腳本

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

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

#!/bin/bash

添加注釋

注釋以#開頭

v第二步:運行腳本

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

chmod +x /PATH/TO/SCRIPT_FILE

/PATH/TO/SCRIPT_FILE

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

bash  /PATH/TO/SCRIPT_FILE

運行腳本

讓通過配置文件定義的特性立即生效

(1)    通過命令行重復定義一次

(2)    讓shell進程重讀配置文件

#source /PATH//FROM/FILE

#. /PATH/FROM/FILE

改變.bash_profile里面PATH變量,使運行腳本的執行路徑改變

root用戶存放的PATH變量

PATH=$PATH:$HOME/bin

普通用戶存放的PATH變量 ,有個隱藏的目錄.local,如果不存在可以自己創建

PATH=$PATH:$HOME/.local/bin:$HOME/bin

shell腳本范例

v#!/bin/bash

v#author:wang

v#Version:1.0

v#Description:Thisscriptdisplayssomeinformationaboutyour#environment

echo"Greetings.Thedateandtimeare$(date)"echo"Yourworkingdirectoryis:$(pwd)"

腳本調試

vbash-n /path/to/some_script

檢測腳本中的語法錯誤

vbash-x /path/to/some_script

調試執行(也具有語法檢測功能)

會把執行過程顯示出來

+和++是層次結構,++是先執行的那層

變量

1.變量

PATH\PWD\USER\OLDPWD\HISTSIZE\HISTFILESIZE\SHELL\HOME\PS1\HISTCONTROL\HISTTIMEFORMAL\UID\HISTFILE

2.命名的內存空間

數據存儲方式:字符

數值:整型,浮點型

布爾值:

3.變量類型

作用:1、數據存儲格式

2、參與的運算

3、表示的數據范圍

類型: 字符

數值:整型、浮點型

4.編程程序語言分類:

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

2.弱類型:無須指定類型,默認均為字符型;參與運算會自動進行隱式類型轉換;變量無須事先定義可直接調用。如:bash 不支持浮點數

5.變量命名法則:

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

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

3、見名知義

4、統一命名規則:駝峰命名法(大駝峰StudentName,小駝峰studentName)

6.bash中變量的種類

1)分類標準:根據變量的生效范圍等標準

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

echo里面表達的是在vartest.sh的腳本中有個localvar1的變量他的值為localvar1

#!/bin/bash

localvar1=haha

echo"vartest1.sh:localvar1=$localvar1"

此時echo$localvar1 沒有反應,這說明自己定義的腳本只能自己使用,只對當前shell有效

[root@localhost ~]# bash vartest1.sh

vartest1.sh:localvar1=haha

sleep  20

運行vartest1腳本的時候相當于在bash的子進程shell中,但是echo$localvar1是在bash進程中的,所以他們不是在一個shell進程中

            wKiom1ev5AyxKzt6AAAJhCHuwek064.png-wh_50              

本地變量不能給子進程使用的例子:

在自己的腳本顯示自己的變量,在自己的腳本顯示localvar1的變量

#!/bin/bash

Lacalvar2=xixi

echo "vartest2.sh:localvar2=$localvar2"

echo "vartest2.sh:localvar1=$localvar1"

sleep 10

vartest1中去調用vartest2,此時vartest1vartest2是父子關系

#!/bin/bash

Localvar1=haha

echo "vartest1.sh:localvar1=$localvar1"

./vartest2.sh

Sleep 10

在子進程中嘗試顯示父進程的變量顯示失敗

[root@localhost~]# ./vartest1.sh

vartest1.sh:localvar1=haha

vartest2.sh:localvar2=xixi

vartest1.sh:localvar1=

原因是因為本地變量不能給子進程使用

wKioL1ev49zjTB9JAAAGoIdfw0o834.png-wh_50

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

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

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

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

2)本地變量

v變量賦值:name=‘value’

v可以使用引用value:

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

(2)變量引用:name=${command}

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

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

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

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

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

v刪除變量:unset name

練習

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

wKioL1ev5CCB_SEbAABpd0NgiW4218.png-wh_50

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

wKiom1ev5C6BidIvAAAjJF2QDJQ350.png-wh_50

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

wKioL1ev5D7w09QlAAAW4CYApes484.png-wh_50

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

3)環境變量

v變量聲明、賦值:

export name=VALUE

declare -x name=VALUE

聲明完之后在腳本中顯示

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

            $ab這種就需要加大括號${a}b.

v顯示所有環境變量export

env

printenv

v刪除:unset name

vbash有許多內建的環境變量:PATH, SHELL, USRE,UID,HISTSIZE, HOME, PWD, OLDPWD, HISTFILE, PS1

環境變量對子進程生效

4)只讀和位置變量

v只讀變量:常量,只能讀,但不能修改和刪除

readonlyname

declare-r name

         一般是常量中會使用

                   declare–rx name 表示既是一個常量又是一個環境變量

         但是隨shell進程終止而終止

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

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

$0:命令本身

$*:傳遞給腳本的所有參數,全部參數合為一個字符串

$@:傳遞給腳本的所有參數,每個參數為獨立字符串

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

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

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

linecount="$(wc-l$1| cut -d' ' -f1)"

echo"$1 has $linecountlines."

算術運算

vbash中的算術運算:help let

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

1.實現算術運算:

(1)   let var=算術表達式

相等的表達方式:

let var =var*5

let var*=5

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

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

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

   expr 1  +  2   屏幕上就出現3

   expr $var  +  2   屏幕就會出現數值

   可以判斷變量是否為整數:expr  $var  +0  就可以了

[root@localhost ~]# var=111

[root@localhost ~]# expr $var + 0

111

[root@localhost ~]# echo $?

0

[root@localhost ~]# expr $var + 0&> /dev/null

[root@localhost ~]# echo $?

0

 

但是乘法的時候需要轉意:

[root@localhost ~]# expr 2 * 3

expr: syntax error

[root@localhost ~]# expr 2 \* 3

6

(5)declare –i var= 數值

[root@localhost ~]# declare -ii=100

[root@localhost ~]# declare -ij=200

[root@localhost ~]# declare -im=i+j

[root@localhost ~]# echo $m

300

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

vbash有內建的隨機數生成器:$RANDOM1-32767

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

如果要表示2-51:echo $[$RANDOM%50+2]

表示1-n:echo $[$RANDOM%N+1]

2.賦值

v增強型賦值:

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

vletvarOPERvalue

例如:let count+=3

自加3后自賦值

[root@localhost ~]# echo $i

100

[root@localhost ~]# let i++

[root@localhost ~]# echo $i

101

[root@localhost ~]# let i–

[root@localhost ~]# echo $i

100

[root@localhost ~]# let ++i

[root@localhost ~]# echo $i

101

[root@localhost ~]# let –i

[root@localhost ~]# echo $i

100

v自增,自減:

letvar+=1

letvar++

letvar-=1

letvar—

[root@localhost ~]# i=100

[root@localhost ~]# let v=i++

[root@localhost ~]# echo $i

101

[root@localhost ~]# echo $v

100

練習

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

wKioL1ev5F_QO2EPAAAQfU9ObkM575.png-wh_50

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

wKioL1ev5GnDZAqKAAAQMbiRIPY516.png-wh_50

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

wKiom1ev5ICzLbtkAAAITQY8Av4899.png-wh_50

邏輯運算

vtrue,false

1,0

v與:

11= 1

10= 0

01 = 0

00 = 0

v:

11= 1

10= 1

01= 1

00= 0

v非:!

!1 = 0

!0 = 1

v短路運算:

短路與:

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

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

短路或:

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

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

v異或:^

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

例如:#command1 && command2

command1為“假”,則command2 不會再執行

否則,command1為“真”,則command2必須執行

#command1 || command2

command1為“假”,則command2 必須執行

否則,command1為“真”,則command2不會再執行

要實現user1用戶不存在就添加用戶user1:id user1 || useradd user1

聚集命令

有兩種聚集命令的方法:

1)復合式

復合式:date; who | wc -l

命令會一個接一個地運行

先執行date,再執行who|wc -l

[root@localhost ~]# who

root     pts/0        2016-08-13 14:17 (10.1.250.108)

[root@localhost ~]# date;who |wc -l

Sat Aug 13 18:26:19 CST 2016

1

2)子shell

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

所有的輸出都被發送給單個STDOUTSTDERR

[root@localhost ~]# (date;who |wc-l) >>/tmp/trace

[root@localhost ~]# cat/tmp/trace

Sat Aug 13 18:28:23 CST 2016

1

兩個命令一起執行可以使用()

[root@localhost ~]# (date;who)|wc -l

2

退出狀態

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

0代表成功,1255代表失敗

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

v例如:

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

$echo$?

-c1為只發一個包;-W1為等待1秒,默認5秒(大寫w)。

退出狀態碼

vbash自定義退出狀態碼

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

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

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

exit例子:

假如編下面的腳本:

#!/bin/bash

echo xxx;(echo zzz ;exit)

echo yyy

就會顯示:

[root@localhost ~]# bash f2.sh

xxx

zzz

yyy

相當于在xxx下面調用一個子進程,子進程內容為echo  yyy

條件測試

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

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

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

若真,則返回0

若假,則返回1

3測試命令:

test EXPRESSION

[ EXPRESSION  ](空格)  [ $a = $b ] [ $a == $b ]

[[ EXPRESSION  ]](空格)[[ $a = $b ]]  [[ $a == $b ]]

盡量使用雙中括號

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

注意:測試命令中其實只要括號內有東西就為真(空格也算),不一定非得比較,[ “ “]其結果為真??梢圆榭匆粋€變量是否被定義過,沒被定義過的則為假。

4)條件性的執行操作符

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

&&代表條件性的ANDTHEN

||代表條件性的ORELSE

v例如:

$grep-qno_such_user/etc/passwd\

||echo'Nosuchuser'

Nosuchuser

$ping-c1-W2station1&>/dev/null\

>&&echo"station1isup"\

>||(echo'station1isunreachable';exit1)

station1isup

test命令

v長格式的例子:

$test"$A"=="$B" && echo"Stringsareequal"(比較字符串用==

$test“$A”-eq “$B” &&echo"Integersareequal"(比較數字用-eq

v簡寫格式的例子:

$["$A"=="$B"]&& echo"Stringsareequal"

$["$A"-eq"$B"]&& echo"Integersareequal"

1數值測試

-gt:是否大于;greaterthan

-ge:是否大于等于;greaterand equal

-eq:是否等于;equal

-ne:是否不等于;not equal

-lt:是否小于;less than

-le:是否小于等于;less anequal

2字符串測試

==:是否等于;

>:ascii碼是否大于ascii

<:是否小于

!=:是否不等于

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

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

-z "STRING":字符串是否為空,空為真,不空為假

-n "STRING":字符串是否不空,不空為真,空為假

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

字符串比較大于小于號必須轉義,即加反斜線。 
         
字符串比較的順序是按ASCII表的順序的,大寫字母比小寫字母的值小。

練習

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

[ $# -lt 1 ] && echo "至少給用戶一個參數" || grep'^$' $1 | wc -l

wKioL1ev5JqDhjgEAAAHtu8kgfQ998.png-wh_50

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

ping -c1 -W1 $1 && echo "該用戶地址可以訪問" || echo "ip地址不可以訪問"

 wKiom1ev5KXh0vRiAAAIUGUH-XE910.png-wh_50

 v3、如果最大磁盤利用率大于百分之20,就報錯

maxuse=`df | grep "dev/sd" | tr -s ' ' ':' |cut -d: -f5 | sed's@%@@' | sort -n | tail -1`

max=20

[[ maxuse -ge max ]] && echo " wall disk will be full!"

wKiom1ev5K_BpeZ6AAAN6NuV6pU104.png-wh_50

3文件測試

1)在性測試

-aFILE:同-e

-e FILE: 文件存在性測試,存在為真,否則為假;

2)存在性及類別測試

-bFILE:是否存在且為塊設備文件;

-cFILE:是否存在且為字符設備文件;

-d FILE:是否存在且為目錄文件;

-f FILE:是否存在且為普通文件;(存在為真)

-hFILE -LFILE:存在且為符號鏈接文件;

-pFILE:是否存在且為命名管道文件;

-SFILE:是否存在且為套接字文件;

3)件權限測試:

-rFILE:是否存在且可讀

-wFILE: 是否存在且可寫

-xFILE: 是否存在且可執行

 

看一個目錄的權限要看實際權限,不能看———,root賬號權限對它是不起作用:

4)文件特殊權限測試:

-gFILE:是否存在且擁有sgid權限;

-uFILE:是否存在且擁有suid權限;

-kFILE:是否存在且擁有sticky權限;

5)文件大小測試:

-sFILE: 是否存在且非空;

非空為真,空為假

6)文件是否打開:

-tfd : fd表示文件描述符是否已經打開且與某終端相關

-NFILE:文件自上一次被讀取之后是否被修改過(讀先發生,寫后發生)就是讀的時間比較舊

-OFILE:當前有效用戶是否為文件屬主

-GFILE:當前有效用戶是否為文件屬組

7)雙目測試:

FILE1–ef  FILE2 : FILE1FILE2是否指向同一個設備上的相同inode(硬鏈接)

FILE1–nt  FILE2 : FILE1是否新于FILE2;(修改的時間)

FILE1–ot  FILE2 : FILE1是否舊于FILE2;(修改的時間)

8)組合測試條件

v第一種方式:

COMMAND1&& COMMAND2 并且

COMMAND1|| COMMAND2 或者

!COMMAND 

如:[ -e FILE ] && [ -r FILE ]

v第二種方式:

EXPRESSION1-a EXPRESSION2 并且

EXPRESSION1-o EXPRESSION2 或者

!EXPRESSION

必須使用測試命令進行,即進行test或者[ ];

意思是只要主機名沒有定義或者主機名為默認就改為www

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

"localhost.localdomain"] && hostname www.magedu.com

判斷/bin/cat是否為可執行文件,如果是就調用

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

練習

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

不管對文件設置什么權限對root用戶是不管用的,所以我們要去普通用戶查看

[ ! -r /tmp/file1 -a ! -w /tmp/file1 ] || echo "用戶對文件不可讀不可寫"

wKioL1ev5MDCD5U6AAAGpgSNr0s764.png-wh_50

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

[ -f /etc/nologin ] && echo "已經禁止普通用戶登入" || (touch /etc/nologin; echo "禁止用戶登入" )

wKioL1ev5MyToPgMAAAJz4xsD9Y054.png-wh_50

[ -f /etc/nologin ] && rm -rf/etc/nologin || echo "普通用戶本身就可以登入系統"

wKiom1ev5NrgCH5WAAAX16bizmA106.png-wh_50

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

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

相關推薦

  • Http虛擬主機的應用

    一、http 1、 基于主機名實現三個虛擬主機 (1)yum安裝httpd (2)注釋中心主機的網頁路徑 (3)創建三個虛擬機主機的文件路徑 (4)創建三個虛擬機主機的文件網頁index.html (5)更改hosts文件進行映射 (6)關閉防火墻和Selinux進行測試(測試步驟是在本機的虛擬機上測試) 2、每虛擬主機使用獨立的訪問日志和錯誤日志 (1)給…

    Linux干貨 2016-10-08
  • find 命令詳解

    Find 命令詳解 find:   實時查找工具, 通過遍歷指定路徑完成文件查找;   工作特點:     查找速度略慢     精確查找     實時查找 可能只搜索用戶具備讀取和執行權限的目錄   語法:   find [OP…

    2017-04-09
  • https介紹

    什么是https HTTP協議傳輸的數據都是未加密的,也就是明文的,因此使用HTTP協議傳輸隱私信息非常不安全。為了保證這些隱私數據能加密傳輸,于是網景公司設計了SSL(Secure Sockets Layer)協議用于對HTTP協議傳輸的數據進行加密,從而就誕生了HTTPS。SSL目前的版本是3.0,被IETF(Internet Engineering T…

    Linux干貨 2017-12-04
  • 五.Linux博客-2016年7月28日索引、硬鏈接、軟連接、inode表、file、重定向、tr、管道、用戶、組

    格式說明: 操作 概念 命令 說明及舉例 五.索引、硬鏈接、軟連接、inode表、file、重定向、tr、管道、用戶、組 索引節點 原數據保存在inode table表中每個文件或目錄都有一個獨立的inode number(節點編號在一個分區中是唯一的,每個分區都有自己的inode table) ls -i 查看節點編號 硬鏈接 ln&n…

    Linux干貨 2016-08-23
  • 沒有自動ip解決辦法

    用虛擬機下載好centos6.9后,本來想查看ip地址,結果發現沒有自動獲取ip地址,在網上找了很多方法都不行,問題如下: 用命令ifconfig查看ip地址,發現沒有,如下 查看eth0如下 解決辦法如下: 1、關閉NetworkManager服務 2、關閉NetworkManager開機啟動 3、添加 /etc/sysconfig/network-scr…

    2017-07-16
  • OpenSSH

    ssh: secure shell, protocol, 22/tcp, 安全的遠程登錄 OpenSSH: ssh協議的開源實現; dropbear:另一個開源實現;  SSH協議版本 v1: 基于CRC-32做MAC,不安全;man-in-middle v2:雙方主機協議選擇安全的MAC方式 基于DH算法做密鑰交換,基于RSA或DSA算法實現身份…

    Linux干貨 2015-06-21
欧美性久久久久