shell腳本編寫的整理(1)

1、shell腳本的特點及用途
2、全局變量、局部變量、本地變量
3、位置變量、特殊變量、只讀變量
4、退出狀態、算數運算、賦值
5、邏輯運算、條件測試、數值測試
6、文件測試、文件權限測試、文件屬性測試
7、read命令、bash的配置

1、shell腳本的特點及用途

程序:指令+數據

程序編程風格:

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

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

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

編程邏輯處理方式:順序執行? ?循環執行? ?選擇執行

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

格式要求:首行shebang機制? ??#!/bin/bash

shell腳本用途:?自動化常用命令 ;執行系統管理和故障排除;創建簡單的應用程序;處理文本或文件

檢查語法錯誤:bash -n f1.sh

調試執行過程:bash -x f1.sh

變量

按數據的存儲方式分為:字符和數字(整型,浮點型)

bash不支持浮點

強類型:變量不經過強制轉換,它永遠是這個數據類型,不允許隱式的類型轉換。一般定義變量時必須指

定類型、參與運算必須符合類型要求;調用未聲明變量會產生錯誤

弱類型:語言的運行時會隱式做數據類型轉換。無須指定類型,默認均為字符型;參與運算會自動進行隱

式類型轉換;變量無須事先定義可直接調用

bash屬于弱類型

name=”mage”

echo $name

mage

如果更改name=”wang”

echo $name

wang

在內存空間里面有另一塊位置被wang占用,原來mage那一個占用并沒有消失!只是沒有了引用

保留原文件的格式必須加雙引號

如name=`cat /etc/fstab`

echo “$name”則有格式

echo? $name 沒有格式

不要使用shell的保留關鍵字如if,for 、,hostname

變量名盡量用英文單詞,不要用英文的簡寫,容易混淆,或者

student_name

統一命名方式:駝峰法

第一個單詞首字母不大寫,后續的所有單詞的首字母全大寫

studentNameFile

 

bash 中變量的種類

運行腳本就是在當前shell開啟一個子進程

顯示當前進程編號

echo $$

查看進程樹命令

pstree -p

新增bash

bash

退出當前bash

exit

2、全局變量、局部變量、本地變量

環境變量

就是全局變量,生效范圍為當前shell進程及其子進程

查詢系統中當前所有環境變量

env

export

declare -x

例子:

1.

export name=mage

則name變為全局變量

在當前以及子進程里執行echo $name都是mage

注意:全局變量只能父進程傳子進程,不能子進程傳父進程

2.刪除變量命令

unset name

注意:這里的變量name不用加$,一般能識別出就不加,但是有些不能識別出的要加,這個要經驗積累.

一般編寫完腳本最后都會用unset命令清楚變量這個是好習慣!!

set? ? ?查看系統所有變量,包括本地變量,環境變量

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

本地變量:生效范圍為當前shell進程中某代碼片段,通常指函數

3、位置變量、特殊變量、只讀變量

位置變量

用于讓腳本在腳本代碼中調用通過命令行傳遞給它的參數

$1 $2 ….:對應調用第1,第2個等參數,shift[n]換位置

例子:

$1,$2表示腳本后的第1和第2個參數

例如:? ? backup.sh a b c

$1就是a? $2就是b

shift? ?變量移動

shift? 移動一次

shift 2? 移動兩次

set — 清空所有位置變量

特殊變量

$0 : 表示命令本身

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

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

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

($@和$*只有被雙引號包起來的時候才會有差異)

$_:前一個命令最后一個字符串

例子:

1.echo a b c? ? 結果a b c

echo $_? ? ? 結果c

2. 在/root/bin下寫腳本arg.sh

echo “1st arg is $1”

echo “2st arg is $2”

echo “3st arg is $3”

echo “All args are $*”

echo “All args are $@”

echo “The args number is $#”

echo “The script name is $0”??? 如果不要路徑名則 `basename $0`

然后執行

arg.sh xxx yy zzzz

顯示

1st arg is xxx

2st arg is yy

3st arg is zzzz

All args are xxx yy zzzz

All args are xxx yy zzzz

The args number is 3

The script name is /root/bin/arg.sh

注意: 如果有第10個參數,則腳本里應寫為:

echo “10st arg is ${10}” 否則系統會把$10誤認為 $1和0上題就是顯示a0

3.scp f1 wang@172.20.102.77:/home/wang/bin

寫腳本scp.sh

echo “Start copy..”

scp $* wang@172.20,102.77:/home/wang/bin

echo “copy is finished”

執行scp.sh f1

就是把f1文件傳送到172.20.102.77里的用戶wang登陸的,/home/wang/bin目錄下

第一次連會問你輸入yes,以后不用,但是要密碼

附帶快速改密碼方法,例如想把wang密碼改成magedu則

echo magedu | passwd –stdin wang

只讀變量

只能聲明,但不能修改和刪除

readnoly name=mage

declare -r name

查看只讀變量:

readonly -p

( )只影響括號里的信息,原理是開啟一個子進程,不影響父進程,而且執行完后子進程自動關閉

換句話說就是(????? )里面的任務是一次性的,而不會影響環境

例如:

1.(umask 666;touch /data/f1)

執行完后系統umask還是0022,f1的權限卻為000

2.想執行一些任務,結束后自動回到當前目錄

(cd /data/ ;rm -rf /data/*)

而{ ; ;? }會影響當前shell的環境

而且格式必須為{ ; ; },括號里兩邊帶有空格

例子:

{?? name=mage;echo $name;? }

echo $name

總結:小括號開啟子shell不影響當前環境,大括號不開啟子shell影響當前環境

一題弄清楚( )的特性

x=1;echo “pid=$$”;(echo “subpid=$$”;echo “subx=$x”;x=2;echo “subx2=$x”);echo x=$x

結果

pid=2887

subpid=2887

subx=1

subx2=2

x=1

說明當前變量可以傳遞到()里面,而()里面的變量不會傳遞到外面,而且()里的子進程號和當前進程號相同。

注意:為腳本創建軟連接腳本,然后執行軟連接腳本,會發現$0參數為軟連接而非原來的腳本,利用這個特性,可

以為同一腳本設置多個軟連接腳本,各軟連接腳本實現不同功能.

4、退出狀態、算數運算、賦值

退出狀態

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

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

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

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

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

令后面的數字

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

的最后一條命令的狀態碼

例如:

靜默模式

grep -q root /etc/passwd

echo $?

0

就是找到了root

返回信息為0就是成功,其他數字就是失敗.

如果想定制返回結果則用 exit num

例如:

ls

exit 10

則echo $?就是10

算數運算

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(0-32767)

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

let 用法

1.

x=10

y=20

let z=x+y

echo $z

30

2.

let x++

x=x+1

echo $x

11

3.

m=2

n=3

sum=$[m+n]

echo $sum

5

4.

對100取模就是取余數

let result=100%3

echo $result

1

或者寫成

result=$[100%3]

echo $result

5.字體隨機顏色

COLOR=$[RANDOM%7+31]; echo -e “\e[1;${COLOR}mcolor\e[0m”

6.expr用于計算

expr 1 + 2

3

記得有空格

expr 3 \* 2

expr 3 / 2

1

是因為不支持浮點

賦值

增強型賦值:

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

let varOPERvalue

例如:let count+=3

自加3后自賦值

自增,自減:

let var+=1

let var++

let var-=1

let var–

x+=2 等價于 x=x+2

5、邏輯運算、條件測試、數值測試

邏輯運算

非: !

! 1=0

! 0=1

0 false

1 true

& 并且 and

0&0=0

0&1=0

1&0=0

1&1=1

| 或者? or

0|0=0

0|1=1

1|0=1

1|1=1

短路與 &&

短路或||

0&&0=0

0&&1=0

1&&0=0

1&&1=1

0||0=0

0||1=1

1||0=1

1||1=1

cmd1 && cmd2

如果cmd1為假,cmd2不需要執行,反之cmd1為真,需要cmd2執行

cmd1||cmd2

如果cmd1為真,cmd2不需要執行,反之cmd1為假,需要cmd2執行

XOR 異或

這里是二進制

0^1=1

0^0=0

1^0=1

1^1=0

例子:

a=2

b=3

let c=a^b

echo $c

1

2的二進制是10

3的二進制是11

10

11

01的二進制就是1

所以結果 $c為1

條件測試

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

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

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

$?

若真,則返回0

若假,則返回1

測試命令

test 命令

例子:

str1=aaa

str2=bbb

test $str1 = $str2

echo $?

1

str2=aaa

test $str1 = $str2

echo $?

0

[ $str1 = $str2 ]

echo $?

0

[ -z $var ]

echo $?

0

(因為 $var 沒有賦值)

var=haha

[ -z $var ]

echo $?

1

[ “abc” ]

echo $?

0

因為”abc”不是變量,屬于”有東西”

[ -n “abc” ]

為非空為真

字符型:

x=haha;y=xixi; [ “$x” = “$y” ] && echo equal || echo no equal

數字型:

m=10

n=20

[ $m -eq $n ] && echo equal || echo no equal

數值測試

-v 測試變量var1是否已經被設置

例:

[ -v var1 ] && echo set

var1=123

運行則顯示 set

注意: “”一樣代表有值!

-v VAR

變量VAR是否設置

數值測試:

-gt 是否大于

-ge 是否大于等于

-eq 是否等于

-ne 是否不等于

-lt 是否小于

-le 是否小于等于

字符串測試:

== 是否等于

> ascii碼是否大于ascii碼

< 是否小于

!= 是否不等于

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

注意: 此表達式一般用于[[ ]]中;擴展的正則表達式

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

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

注意:用于字符串比較時的用到的操作數都應該使用引號,就是在中括號里面都應該加引號

[ “$var” = “” ] 等價 [ -z “$var ]

例子

判斷wang用戶對文件是否有讀和寫的權限同時有則打印讀和寫

[ -r /etc/issue -a -w /etc/passwd] && echo “read and write”

沒顯示,如果改成-o則有顯示

-a 是并且的關系

-o 是或者關系

設置一個腳本如果磁盤利用率高于等于80%則報警

USE_RATIO=`df | grep “sd[a-z]” | tr -s ‘ ‘ ‘%’ |cut -d% -f5 |sort -nr | head -1`

[ $USE_RATIO -ge 80 ] && `wall “disk will be full” `

=~ 要用[[]],而且是擴展正則表達式

例子:

1.n=12

[[ “$n” =~ ^[0-9]+$ ]] && echo digit || echo no digit

digit

2.! 1=0

!? 0=1

[ $# -ne 2 ]? && echo “Arg number is 2” && exit

[[? !? “$1” =~ ^[0-9]+$ ]]? && echo “$1 is not digit ” && exit

[[? !? “$2” =~ ^[0-9]+$ ]]? && echo “$1 is not digit ” && exit

uid1=`head -n$1 /etc/passwd | tail -n1 |cut -d: -f3`

uid2=`head -n$2 /etc/passwd | tail -n1 |cut -d: -f3`

echo sum=$[uid1+uid2]

3..sh后綴的文件則顯示sh非則no sh

[[? $filename =~ .+\.sh$ ]] && echo sh || echo no sh

4.判斷用戶是否存在,存在則退出,不存在則創建用戶并設置密碼magedu

id $1 &> /dev/null

[ $? -eq 0 ] && echo user is exist && exit

useradd $1

echo magedu | passwd –stdin $1 &> /dev/null

echo “$1 is created”

6、文件測試、文件權限測試、文件屬性測試

存在性測試

-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: 是否存在且可執行

文件特殊權限測試:

-u FILE:是否存在且擁有suid權限

-g FILE:是否存在且擁有sgid權限

-k FILE:是否存在且擁有sticky權限

文件大小測試:

-s FILE: 是否存在且非空

文件是否打開:

-t fd: fd 文件描述符是否在某終端已經打開

-N FILE:文件自從上一次被讀取之后是否被修改過

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

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

7、read命令、bash的配置

read 命令

使用read來把輸入值分配給一個或多個shell變量

-p 指定要顯示的提示

-s 靜默輸入,一般用于密碼

-n N 指定輸入的字符長度N

-d ‘字符’ 輸入結束符

-t N TIMEOUT為N秒

read 從標準輸入中讀取值,給每個單詞分配一個變量

所有剩余單詞都被分配給最后一個變量

read -p “Enter a filename: “ FILE

例子:

1.read -p “Please input your name :” name

read -p “Please input your password :” passwd

echo “Your name is $name”

echo “Your password is $password”

2.頭 35 腳 94 答案雞23? 兔 12

read -p ” head number : ” head

read -p ” feet number : ” feet

chook=$[(head*4-feet)/2]

rabbit=$[head -chook]

echo “chook number is $choook , rabbit number is $rabbit ”

完美版:

read -p “please input the head number :” head

read -p “please input the feet number :” feet

let chook=(4*head-feet)/2

let rabbit=head-chook

echo “the chook number is $chook ,the rabbit number is $rabbit”

bash如何展開命令行

1.把命令行分成單個命令詞

2.展開別名

3.展開大括號的聲明({})

4.展開波浪符聲明(~)

5.命令替換$() 和 “)

6.再次把命令行分成命令詞

7.展開文件通配(*、 ?、 [abc]等等)

8.準備I/0重導向(<、 >)

9.運行命令

shell登錄兩種方式

交互式登錄:

(1)直接通過終端輸入賬號密碼登錄

(2)使用“ su – UserName” 切換的用戶

執行順序:/etc/profile –> /etc/profile.d/*.sh –> ~/.bash_profile –>

~/.bashrc –> /etc/bashrc

非交互式登錄:

(1)su UserName

(2)圖形界面下打開的終端

(3)執行腳本

(4)任何其它的bash實例

執行順序: ~/.bashrc –> /etc/bashrc –> /etc/profile.d/*.sh

批量賦值

支持重定向賦值

echo a b c > f1

read x y z < f1

echo $x? ; echo $y ; echo $z

a???????????? b??????? c

會顯示賦值成功

cat f1

aaa

bbb

ccc

cat f1 | read x y z

這樣會賦值失敗

read x y x <<< “i j k”

這樣會賦值成功

判斷yes和no

read -p “Do you agree ? yes or no:” ANS

[[ $ANS =~ ^([Yy]([Ee][Ss])?)$ ]] && echo “your answer is yes”

[[? $ANS? =~? ^([Nn][Oo]?)$? ]] && echo “your answer is no”

[[ !? $ANS =~ ^([Yy]([Ee][Ss])?)$? ]] && [[? ! $ANS? =~? ^([Nn][Oo]?)$? ]]? && echo “please input yes or

no”

配置文件總結

按生效范圍劃分,存在兩類:

全局配置:

/etc/profile

/etc/profile.d/*.sh

/etc/bashrc

個人配置:

~/.bash_profile

~/.bashrc

/etc下的都是全局的

交互式登錄:

(1)直接通過終端輸入賬號密碼登錄

(2)使用“ su – UserName” 切換的用戶

執行順序:/etc/profile –> /etc/profile.d/*.sh –> ~/.bash_profile –>

~/.bashrc –> /etc/bashrc

非交互式登錄:

(1)su UserName

(2)圖形界面下打開的終端

(3)執行腳本

(4)任何其它的bash實例

執行順序: ~/.bashrc –> /etc/bashrc –> /etc/profile.d/*.sh

注意:? 一般腳本運行都是在子進程里運行

source + 腳本? ?這樣是在當前shell運行,而不是在子進程里運行

注意:

1.設置文件寫在~/.bashrc和/etc/profile.d/*.sh下則交互式登陸和非交互式登陸下都會執行但是為了保持系

統穩定性,一般推薦在/etc/profile.d/*.sh下建立。

2.腳本里不支持別名命令!!

例如直接寫alias 都不支持

3.用戶退出時的環境初始化也可以實現

.bash_logout

例如想實現退出后自動清空data下的文件

則可以把rm -rf /data/*寫入.bash_logout這樣就可以了.

4.$- 有特定的含義,代表功能的組合

默認顯示himBH

h:代表哈希 hashall ,打開這個選項后,shell會將命令所在的路徑hash下來,避免每次都要查詢.

set +h 關閉選項

set -h 打開選項

i:interactive-comments,有這個選項說明當前shell是一個交互式的shell.

在腳本中,i選項是關閉的.

m:monitor,打開監控模式,就可以通過Job control來控制進程的停止、繼

續,后臺或者前臺執行等。

B:braceexpand,大括號擴展

H:history,H選項打開,可以展開歷史列表中的命令,可以通過!感嘆號來完成,例如“!!” 返回上最近的一

個歷史命令,“!n” 返回第 n 個歷史命令

 

本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/95936

(0)
MaxMax
上一篇 2018-04-14 17:04
下一篇 2018-04-14

相關推薦

  • Homework_week1

    一、描述計算機的組成及其功能 計算機是由運算器、控制器、存儲器、輸入設備、輸出設備五大部件組成,每個部件的功能如下:運算器:完成各種算術運算和邏輯運算的裝置,能進行加、減、乘、除等數學運算,也能作比較、判斷、查找、邏輯運算等;?控制器:控制器是整個計算機系統的控制中心,它指揮計算機各部分協調地工作,保證計算機按照預先規定的目標和步驟有條不紊的進行操作及處理;…

    2018-06-20
  • RAID和邏輯卷

    1、RAID技術
    2、RAID實驗
    3、邏輯卷管理
    4、邏輯卷快照

    Linux筆記 2018-06-10
  • SELinux簡介

    SELinux(Security-Enhanced Linux) 是美國國家安全局(NSA)對于強制訪問控制的實現,是Linux歷史上最杰出的新安全子系統。NSA是在Linux社區的幫助下開發了一種訪問控制體系,在這種訪問控制體系的限制下,進程只能訪問那些在他的任務中所需要文件。

    2018-05-15
  • 第二周:Linux文件管理命令以及bash的工作特性

    一、Linux文件管理命令 1. cp命令 ● 命令格式 單源復制:cp [OPTION]… [-T] SOURCE DEST 多源復制:cp [OPTION]… SOURCE… DIRECTORY ? ? ? ? ?cp [OPTION]… -t DIRECTORY SOURCE…   ● 命令功能 復制文件 ● 命令選項 -…

    2018-05-16
  • aide

    aide 實現查看文件是否篡改 查看是否被攻擊 aide 的主配置文件 /etc/aide.conf aide的日志 /var/log/aide aide的數據庫 /var/lib/aide (用于存放比對信息數據) 在 /etc/aide.conf 里 定義你自己的要檢查的什么屬性 在 后面調用就行 比如 /date/ rules !/date/f1 監控…

    Linux筆記 2018-05-27
欧美性久久久久