九、shell编程
變量初始化:在變量聲明的時候給變量一個初始值,初始化相當于給里面放東西。
變量賦值:手動給變量空間中存儲數據的過程。
變量類型轉換:顯式、隱式,比如講字符型轉換成數值型。
變量類型:
? ? ?本地變量: ??
? ? ? ? ? ? ? ? ? ? ? ? ? set var_name=value
? ? ? ? ? ? ? ? ? ? ? ? ? unset var_name
? ? ? ? ? ? ? ? ? ? ? ? ? ${var_name}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?作用范圍:當前shell進程。
? ? ? 局部變量:
? ? ? ? ? ? ? ? ? ? ? ? ? ?local var_name=value?
? ? ? ? ? ? ? ? ? ? ? ? ? ?unset var_name
? ? ? ? ? ? ? ? ? ? ? ? ? ?${var_name}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 作用范圍:當前shell進程的局部范圍內有效
? ? ? 環境變量:
? ? ? ? ? ? ? ? ? ? ? ? ? ?export var_name=value
? ? ? ? ? ? ? ? ? ? ? ? ? ?unse var_name
? ? ? ? ? ? ? ? ? ? ? ? ? ?${var_name}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?作用范圍:當前shell及其子shell。
? ? ? ?位置變量:$1/$2................
? ? ? ?特殊變量:$$/$?/$#/$@...................
腳本的寫法格式:
? ? ? ? ?指定腳本運行的shell環境:
? ? ? ? ? ? ? ?獨立執行腳本的條件:?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1、要有執行權限。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?2、定義好shebang,及腳本的第一行:#! /path/to/explainer 例如:/bin/bash ,/usr/bin/python。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?3、定義命令的path環境變量。
bash的配置文件:
?profile:聲明環境變量,執行程序腳本 ,/etc/profile,/etc/profile.d/*.sh,~/bash_profile,交互式登陸
bashrc:定義本地變量、定義命令別名/etc/bashrc,~/.bashrc,非交互式
腳本文件中,除第一行外其他所有已#開頭的行均為注釋行。
練習一、添加一組用戶,并且用戶名同密碼一樣。
? ? ? ? ? ? ? ?#!/bin/bash
? ? ? ? ? ? ? ?#author:gongbing
? ? ? ? ? ? ? ?#time :20150731
? ? ? ? ? ? ? ?#version:1.0
? ? ? ? ? ? ? ?#description:add user?
? ? ? ? ? ? ? ?useradd user1
? ? ? ? ? ? ? ?echo user1 |passwd --stdin user1&>/dev/null
? ? ? ? ? ? ? ?echo "add user1 successful!"
? ? ? ? ? ? ?
? ? ? ? ? ? ? ?useradd user2
? ? ? ? ? ? ? ?echo user2 |passwd --stdin user2 >/dev/null
? ? ? ? ? ? ? ? echo "add user1 successful!"
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? useradd user3
? ? ? ? ? ? ? ? echo user3 |passwd --stdin user3 >/dev/null
? ? ? ? ? ? ? ? echo "add user1 successful!"
編寫完畢保存為.sh文件,并賦予執行權限。
檢查腳本的語法錯誤:
? ? ? ? ? bash -n 腳本路徑/腳本名
? ? ? ? ? ? ? ?
調試執行腳本語法:
? ? ? ? ? ?bash -x /path/to/script_file.sh
變量名稱取名規則:
? ? 1、數字、字母、下劃線
? ? 2、不能以數字開頭
? ? 3、區分大小寫
? ? 4、風格統一,見名知意。
面向過程的編譯語言,都有語言控制結構:
?1、順序執行:默認、逐條執行。
?2、選擇執行:依據條件語句判斷來選擇執行的步驟。 0:真,非零:假
?3、循環執行:依據條件重復執行某一條命令的次數。
控制語句:
不同語句寫在同一行里需要用分號;隔開。
? ? ? ? ?bash循環控制語句:
? ? ? ? ? ? ? for循環:
? ? ? ? ? ? ? ? ? 事先提供一個元素列表,然后讓變量去遍歷(挨個提取)此元素列表;每訪問一個元素,執行一次循環體,直至元素遍歷完畢。
? ? ? ? ? ? ? ? ? ? ? 用法: for var_name in 元素列表比如元素1 元素2 元素3
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?do ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?語句1;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?語句2;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?done
? ? ? ? ? ? ? while
? ? ? ? ? ? ? until
練習二:給練習一調整為循環語句。
? ? ? ? ? ? ? #!/bin/bash
? ? ? ? ? ? ? ? ? for username in user1 user2 user3;
? ? ? ? ? ? ? ? ? ?do;
? ? ? ? ? ? ? ? ? ? ? ? useradd $username ;
? ? ? ? ? ? ? ? ? ? ? ? echo $username |passwd --stdin $username;
? ? ? ? ? ? ? ? ? ? done;
? ? ? ? ? ? ??
練習三 、顯示/et/inittab,/etc/rc.d/rc.sysinit,/etc/fstab三個文件各有多少行。
? ? ? ? ? ? ? #!/bin/bash
? ? ? ? ? ? ? for PathWc in /etc/inittab /etc/rc.d/rc.sysinit /etc/fstab?
? ? ? ? ? ? ? do
? ? ? ? ? ? ? ? ? ?cat $PathWc |wc -l?
? ? ? ? ? ? ? done
練習:
? ? ? ? ? ?1、 使用for循環創建/tmp/1.dir,/tmp/2.dir和/tmp/3.dir,權限為750
? ? ? ? ? ? ? #!/bin/bash
? ? ? ? ? ? ? for Direc_Gest in 1.dir 2.dir 3.dir
? ? ? ? ? ? ? do
? ? ? ? ? ? ? ? ? ? mkdir /tmp$Dire_Gest
? ? ? ? ? ? ? ? ? ? chmod 750 /tmp/$Dire_Gest
? ? ? ? ? ? ? ?done
? ? ? ? ? ?
? ? ? ? ? ? ?2、統計/etc/fstab、/etc/rc.d/rc.sysinit、/etc/inittab文件中各自以#開頭的行的行數和空白行行數。
? ? ? ? ? ? ? ? ? ?#!/bin/bash
? ? ? ? ? ? ? ? ? ?for filecount in /etc/fstab /etc/rc.d/rc.sysinit /etc/inttab
? ? ? ? ? ? ? ? ? ?do
? ? ? ? ? ? ? ? ? ? ? ?egrep ^#|^$ $filecount |wc -l
? ? ? ? ? ? ? ? ? ?done
? ? ? ? ? ? ? 3、將/etc/passwd 、/etc/shadow的最近一次修改時間改為2010年3月12日14:11 3秒
? ? ? ? ? ? ? ? ? ? #!/bin/bash
? ? ? ? ? ? ? ? ? ? for ModfyTime in ?/etc/passwd /etc/shadow
? ? ? ? ? ? ? ? ? ? do?
? ? ? ? ? ? ? ? ? ? ? ? ?touch -m -t 201003121411.03 $ModfyTime
? ? ? ? ? ? ? ? ? ? #touch -a 修改訪問時間 默認當前時間
? ? ? ? ? ? ? ? ? ? #touch -m 修改修改時間 當前時間
? ? ? ? ? ? ? ? ? ? #touch -m -t yymmddhhmm.ss 修改指定時間。
? ? ? ? ? ? ? ? ? ? ?done
? ? ? ? ? ? ? 4、將user1、user2、user3加入到testgrp組中,以其為額外組。
? ? ? ? ? ? ? ? ? ? ?#!/bin/bash
? ? ? ? ? ? ? ? ? ? ?groupadd testgrp
? ? ? ? ? ? ? ? ? ? ? for usertogrp in 1 2 3?
? ? ? ? ? ? ? ? ? ? ? do
? ? ? ? ? ? ? ? ? ? ? ? ? ?usermod -G testgrp user$usertogrp
? ? ? ? ? ? ? ? ? ? ? ?done
? ? ? ? ? ? ?5、copy /etc/passwd /etc/shadow /etc/inittab 到/tmp/目錄下,并將名稱已當前時間進行重命名。
? ? ? ? ? ? ? ? ? ? ?#!/bin/bash
? ? ? ? ? ? ? ? ? ? ?for filerename in ?/etc/passwd /etc/shadow /etc/inittab
? ? ? ? ? ? ? ? ? ? ? ? do ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?basefile= `basename $filerename`
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?cp $filename /tmp/$basefile-`date +%F`
? ? ? ? ? ? ? ? ? ? ? ? ? done
? ? ? ? ? ? ? ? 6、顯示/etc/paswd文件的第1、3、6、12個用戶的用戶名、id、基本組的組名。
? ? ? ? ? ? ? ? ? ?#!/bin/bash
? ? ? ? ? ? ? ? ? ?for Line in 1 3 6 12?
? ? ? ? ? ? ? ? ? ? do
? ? ? ? ? ? ? ? ? ? ?username=`head -n 1 /etc/passwd |tail -n 1 |cut -d : -f 1`
? ? ? ? ? ? ? ? ? ? ?Idname=`head -n 1 /etc/passwd |tail -n 1 |cut -d : -f 3` ? ? ? ??
? ? ? ? ? ? ? ? ? ? ?Groupname='id -gn $username'
? ? ? ? ? ? ? ? ? ? echo "username:$username idname=$Idname groupname=$Groupname"
? ? ? ? ? ? ? ? ? ?done
列表的生成:
? ? ? ? 1、逐個列出,例如1 2 3 4
? ? ? ? 2、使用通配符列出,例如 /etc/*
? ? ? ? ? ? ? ? ? ?#!/bin/bash
? ? ? ? ? ? ? ? ? ?for file in /etc/*
? ? ? ? ? ? ? ? ? ? ? do
? ? ? ? ? ? ? ? ? ? ? ? ? file $file
? ? ? ? ? ? ? ? ? ? ? ?done
? ? ? ? ? 3、使用命令生成列表。
? ? ? ? ? ? ? ? ? #!/bin/bash
? ? ? ? ? ? ? ? for File in `ls ?/var`
? ? ? ? ? ? ? ? ? ?do
? ? ? ? ? ? ? ? ? ? ? ? file /var/$File
? ? ? ? ? ? ? ? ? ?done
? ? ? ? ? ?4、生成數字序列,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {}:例如生成1到100的數值,{1..100}
? ? ? ? ? ? ? ? ? ? ? ? ? ? equ:equ [起始數字] [步長] [結束數字]
練習:
? ? ? ? ? ?1、取出每個用戶的用戶名和shell
? ? ? ? ? ? ? ? ? ? ?思路:首先需要確定行數
? ? ? ? ? ? ? ? ? #!/bin/bash
? ? ? ? ? ? ? ? ? ? ?line=`wc -l /etc/passwd |cut -d : f 1`
? ? ? ? ? ? ? ? ? ? ?for Line in equ 1 $line
? ? ? ? ? ? ? ? ? ? ?do
? ? ? ? ? ? ? ? ? ? ? ? ? head -$Line /etc/passwd |tail -1 |cut -d: -f 1,7
? ? ? ? ? ? ? ? ? ? ? ?done
如何在shell中進行算術運算
?shell不支持浮點數(小數),計算結果中如果有浮點數會被圓整為正數(化零為整)
默認變量使用的是字符變量類型。實現算數運算的方法:
1、 ? $[變量名]=valume
2、 ? $((變量名))=valume
3、 let ? ? 例如:let a=$a+$b
4、 expr ?例如:f=`expr $a + $b`
練習:
? ? ? ? ? ?隨意聲明兩個變量,并給出整數值,然后計算他們的加減乘除的結果。
? ? ? ? ? ? #!/bin/bash
? ? ? ? ? ? Valume1=12
? ? ? ? ? ? Valume2=43
? ? ? ? ? ? for suanfa ? in + - * /
? ? ? ? ? ? do
? ? ? ? ? ? ? ? ?echo "$Valume1$suanfa$Valume2= `let $Valume$suanfa$Valume`"
? ? ? ? ? ? ?done
選擇執行語句
可以獨自執行的命令不需要添加[]來完成測試。
?bash條件測試方式有以下幾種:
1、 ? ?[ expression ]:[]里面有空格。表示條件選擇的依據。
2、 ? ?` expression `:
3、 ? ?test ?expression:
4、 ? ?bash 命令:
bash執行命令后有執行結果的狀態返回值:echo $? (0表示成功,其他都是錯誤)
可以使用exit命令在腳本中自定義腳本執行狀態返回值,如果沒有定義,腳本執行狀態返回值取決于腳本執行結束前的最后一條語句的執行結果。
判斷格式:
? ?單分支if語句:
? 1、 if 條件 ;then
? ? ? ? 語句1
? ? ? ? 語句2
? ? fi
練習:?
? ? ? ? 1、查看某用戶是否存在,并顯示相關信息。
? ? ? ? ? ? ? ? ? #!/bin/bash
? ? ? ? ? ? ? ? ? ?Username=user1
? ? ? ? ? ? ? ? ? ?if id $Username &>/dev/null
? ? ? ? ? ? ? ? ? ? ? ?then
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?echo "$Username is living"
? ? ? ? ? ? ? ? ? ? fi
? ? ? ? 2、如果用戶存在,顯示用戶id和shell信息。
? ? ? ? 3、如果一個設備已經掛載,顯示掛載點。
? ? ? ? 4、??檢查某一文件的 的空白行,并統計行數。
?? ? ? ? ? ? ? ? ?
? 2、if 條件
? ? ? ? ? ?then?
? ? ? ? ? ? ? ? ?語句1
? ? ? ? ? ? ? ? ?語句2
? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? 語句1
? ? ? ? ? ? ? ? ? 語句2
? ? ? ? ?fi
練習:
? ? ? ? ? 1、檢查用戶是否存在,并顯示相關信息,如果不存在創建用戶名,密碼。
? ? ? ? ? ? ? ? ? #!/bin/bash
? ? ? ? ? ? ? ? ? Username=zhangliang
? ? ? ? ? ? ? ? ? ? ? ?if id $Username &>/dev/null
? ? ? ? ? ? ? ? ? ? ? ? ? then
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?echo "$Username is living"
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?echo "$Username id&shell is`grep "$Username:" /etc/passwd |cut -d : -f 3,7`"
? ? ? ? ? ? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?useradd $Username
? ? ? ? ? ? ? ? ? ? ? ? ? ? echo "no this username,please wait....useradding...... ? "
? ? ? ? ? ? ? ? ? ? ? ? ? ? echo "$Username" |passwd --stdin $Username
? ? ? ? ? ? ? ? ? ? ? ? ? ? echo "$Username id&shell is `grep "$Username:" /etc/passwd |cut -d : -f 3,7`"
fi
整數測試:
? ? ? ? ? expression: 數值1 比較符號 數值2
? ? ? ? ? ? ?比較符號:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-gt:大于號
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-ge:大于或等于號
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-eq:等于號
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -lt:小于號
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -le:小于或等于
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -ne:不等于
例如,寫一個腳本,隨意生成兩個整數,比較其大小,顯示大數。
#!/bin/bash
a=$RANDOM b=$RANDOM if [$a -gt $b ] then echo "the max number is $a" else echo "the max number is $b" fi2、給定一個整數,判定奇偶性。
3、給定一個用戶,如果其ID號大于499,就顯示其為普通用戶,否則顯示其為管理員。
4、給定一個用戶,如果其uid等于gid,就說明這個是“good guy”否則顯示“bad guy”
#!/bin/bash Username=pulse if [ `id -u $Username` -eq `id -g $Username` ] then echo "this user($Username) is good guy! " elseecho "this user($Username) is bad guy!"
? ?嵌套練習:
? ? ? ? ? ? ? ? ? ?求200以內的所有為3的整數倍的整數之和
#!/bin/bash sum=0 for n in {1..100} do if [ $[$n%3] -eq 0 ] then sum=$[$sum+$n] fi done echo "300 zhengshu he equal is $sum"? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
bash編程之位置變量
? ? ? $1.....$11.......:表示可以通過執行程序,然后加常量的方式來執行并替換程序中的$1等相關變量。
? ? ? ? ? ? ? ? ? $@:表示可以將多個常數按照一個字符串的形式顯示出來
? ? ? ? ? ? ? ? ? $*:將多個常數分別以各自字符串的形式顯示出來。
? ? ? ? ? ? ? ? ? $#:匯總常數的個數。
? ? ? ? ? ? ? ? ? $0:腳本名稱。
? ? ? ? ? ? ? #!/bin/bash
? ? ? ? ? ? ? ? echo $1
? ? ? ? ? ? ? ? echo $2
? ? ? ? ? ? ? ? echo $@
? ? ? ? ? ? ? ? echo $*
? ? ? ? ? ? ? ? echo $#
? ? 執行程序:./pos.sh a b c d e
? ? 執行結果:a
? ? ? ? ? ? ? ? ? ? ? b?
? ? ? ? ? ? ? ? ? ? ? a b c d e
? ? ? ? ? ? ? ? ? ? ? a b c d e
? ? ? ? ? ? ? ? ? ? ? 5
例:通過參數傳遞n個正整數給腳本,并求和。
#!/bin/bash Num=0 Count=0 for n in $@ do Count=$[$Count+$n] done echo "Count is $Count"shift:對一組數進行重新定位第一個數。shift之前的數被踢掉。
? ? ? ? ? ?實現位置參數輪替。
? ? ? ? ? ? ? ?#!/bin/bash
? ? ? ? ? ? ? ? ? echo $1
? ? ? ? ? ? ? ? ? shift
? ? ? ? ? ? ? ? ? ?echo $1
? ? ? ? ? ? ? ? ? ?shift
? ? ? ? ? ? ? ? ? ?echo $1
? ? ? ? ? ? ?執行:./shift.sh a b c d?
? ? ? ? ? ? ?結果:a?
? ? ? ? ? ? ? ? ? ? ? ? b?
? ? ? ? ? ? ? ? ? ? ? ? c
練習:
? ? ? ? ?添加10個用戶,需要先判斷用戶是否存在,如果不存在才添加,統計添加的用戶數,并顯示總的用戶數。
? ? ? ? ? ? ? ? ? ??
#!/bin/bash countaddu=0 for n in `seq 1 10` do if [ `grep "user$n" /etc/passwd` &>/dev/null ] then echo "old user" else adduser user$n countaddu=$[$countaddu+1] fi done echo "adduser count is $countaddu" echo "countuser is :`wc -l /etc/passwd`"字符測試:
文件測試:
默認變量使用的是字符變量類型。實現算數運算的方法:
1、 ? $[變量名]=valume
2、 ? $((變量名))=valume
3、 let ? ? 例如:let a=$a+$b
4、 expr ?例如:f=`expr $a + $b`
— +:對兩個變量做加法。
— -:對兩個變量做減法。
— *:對兩個變量做乘法。
— /:對兩個變量做除法。
— **:對兩個變量做冪運算。
— %:取模運算,第一個變量除以第二個變量求余數。
— +=:加等于,在自身基礎上加第二個變量。
— -=:減等于,在第一個變量的基礎上減去第二個變量。
— *=:乘等于,在第一個變量的基礎上乘以第二個變量。
— /=:除等于,在第一個變量的基礎上除以第二個變量。
— %=:取模賦值,第一個變量對第二個變量取模運算,再賦值給第一個變量。
?(1)、在括號運算中((i=$j+$k))運算符號兩邊可以有空格也可以沒有空格,但是expr運算i=`expr $j + $k`中運算符號兩邊必須要有空格!
?(2)、乘法運算符號是 \* ,而不是 * ;除法運算 / 表示整除,1/2=0。
2、Let expressions? 執行一個或多個表達式。
????? ? ? (1)、表達式中的變量前不必有$.
???????? (2)、如果表達式中包含了空格或其他特殊字符,則必須引起來。(let i=i+1中除了let后面有一個空格外,其他地方不能有一個空格!)
????????? 例:let “I = I + 1” 或 let i=i+1
bash腳本的知識點:
?條件測試方式:
? ? bash命令:?
? ? ? ? ?[ expression ]
? ? ? ? ?test?expression
? ? ? ? ?` expression `
條件測試的方法:
? ? ? ? ?整數測試:
? ? ? ? ? ? ? ? ? ? ? ?大于:-gt?
? ? ? ? ? ? ? ? ? ? ? ? 小于:-lt
? ? ? ? ? ? ? ? ? ? ? ? ?等于:-eq
? ? ? ? ? ? ? ? ? ? ? ? 大于等于:-ge
? ? ? ? ? ? ? ? ? ? ? ? 小于等于:-le
? ? ? ? ? ? ? ? ? ? ? ? 不等于:-ne
? ? ? ? ?字符測試
? ? ? ? ?文件測試
? ?命令狀態返回值:0 正確
? ?exit [n] :腳本執行的最后一條命令的狀態返回值,
? ? ? ? ?
bash字符測試:
? ?>:大于
? ?<:小于
? ?==:等于
? ?=~:判定左邊的字符串是否能夠被右邊的模式所匹配,通常使用` `,[]內需要空格。
? ? ? ? ?模式要求: 一般做行尾、行首錨定($^等),不可以做詞尾錨定,不能加引號
? ?單目操作:一個操作數,
? ? -z $string:為空則為真,不空為假。
? ?-n $string:為空則為假,不空為真。
例子:寫一個腳本,判定用戶的shell是否為bash。
#!/bin/bash hell=`grep "$1:" /etc/passwd |cut -d : -f 7` if [ $hell == "/bin/bash" ] then? ? echo "this is bash user"
? ? ret =0
else? ? echo "this is not bash user"
? ?ret =8
fi? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?exit $ret
bash的特殊參數:$0 scriptsname
如果腳本是帶路徑的時候,要提取腳本名使用如下命令:
basename $0
bash編程之位置變量
? ? ? $1.....$11.......:表示可以通過執行程序,然后加常量的方式來執行并替換程序中的$1等相關變量。
? ? ? ? ? ? ? ? ? $@:表示可以將多個常數按照一個字符串的形式顯示出來
? ? ? ? ? ? ? ? ? $*:將多個常數分別以各自字符串的形式顯示出來。
? ? ? ? ? ? ? ? ? $#:匯總常數的個數。
? ? ? ? ? ? ? ? ? $0:腳本名稱。 ?如果是帶路徑的$0 ,使用basename $0
bash知識點:組合條件測試
? ? ? ? -a:與
? ? ? ? -o:或
? ? ? ? ?!:非 單目操作
寫一個腳本:給定用戶,如果其不存在,就退出腳本。
#!/bin/bash if ?! id $1 &>/dev/null then exit 6 else echo user is exist fibash之if多分支語句語法講解及腳本練習
多分支if語句
語法格式:
? ? ? ? ?if 條件;then
? ? ? ? ? ? ?語句1
? ? ?elif ?條件2;then
? ? ? ? ? ? ? 語句1
? ? ?elif ? 條件3;then
? ? ? ? ? ? ? ?語句
? ? ? ?else
? ? ? ? ? ? ? 語句
? ? ? ? fi
練習:
判斷當前主機的cup制造商,其信息在/proc/cpuinfo文件中vendor id 一行。
如果制造商是genuineintel ,就顯示為intel
如果制造商是authenticamd,就顯示amd
否則,顯示無法識別。
#!/bin/bash
Vendor=`grep "vendor_id" /proc/cpuinfo |uniq |cut -d : -f 2`
if [[$Vendor =~ [[ :space: ]]*GenuienIntel$]];
? ? then
? ? ? ? ?echo "intel"
elif [[$Vendor =~ [[ :space: ]]*AuthenticAMD$]];
? ? ?then
? ? ? ? ? echo "AMD"
fi
2、通過參數傳遞給一個腳本參數,如fedora,gentoo,redhat,判斷linux發行版所處的發行系列。
? ? ?如果為fedora,centos,redhat,就顯示為redhat
? ? ? ? [ $1 == fedora -o $1 == centos -o $1 == redhat ]
? ? ?如果為suse,opensuse,就顯示為suse
? ? 如果是ubuntu,mint、debian,就顯示為debian
? ?否則,顯示為其他。
bash測試之文件測試
方法:操作符 ?文件路徑
-f:測試其是否是普通文件,即文件類型為-。
?-d:測試其是否為目錄文件,文件類型d
?-e:測試文件是否存在,存在為真,否則為假。
?-r:測試文檔對當前用戶來說是否可讀。
-w:測試文件對當前用戶是否可寫。
-x:測試文件是否對當前用戶可執行。
-s:測試文件內容是否為空,不空為真,否則為假。
-l:測試文件是否是鏈接文件。
練習:如果/tmp/test10文件不存在,就創建之:
if [ ! -e /tmp/test10 ];
then
? ? ? mkdir /tmp/test10
fi
短路操作:
與運算:&& 全真則真 ,有假則假
或運算:|| 有假則全假,有真則全真
通過以上運算思路,可以確定如果一個運算的前半部分是真,對于與運算,就需要進行后面的運算才能知道結果是真還是假,如果是用或運算,則知道前面是假可以推斷出后面是任何運算都為假,也就沒有必要進行后面的運算。這個就是短路運算的思維。
比如:
前面的運算為真,確實存在這個文件,就不會進行后面的操作,如果前面為假,則會進行后面的操作。
1、mkdir /backup
? ? ?tar Jcf /backup/etc-`date +%f`.tar.xz /etc/*
2、tar xf /backup/etc-2013-07-22.tar.xz -C /var/tmp/
3、 ? ? ? ? ? ? ? #!/bin/bash?
comdec=$1? if [ -z $comdec ]; then comdec=gzip fi [ -d /backup ] || mkdir /backupif ?[ $comdec == 'gzip' ]; then tar zcf /backup/etc-`date +%F-%H-%S`.tar.gz /etc/* [ $? -eq 0 ] && echo "backup etc finished.(gzip)" elif [ $comdec == 'bzip2' ]; then tar jcf /backup/etc-`date +%F-%H-%S`.tar.bz2 /etc/* [ $? -eq 0] && echo "backup etc finished.(bzip2)" elif [ $comdec == 'xz' ]; then tar Jcf /backup/etc-`date +%F-%H-%S`.tar.xz /etc/* [ $? -eq 0 ] && echo "backup etc finished.(xz)" else echo "usage: `basename $0` {[gzip|bzip2|xz]}" exit 6 fi
bash編程之CASE語句:
case 變量引用(${}) in value1)? ? ?語句
? ? ?;;
value2)語句
;;
value3)語句
;;
*)
語句
esac #!/bin/bashif [ -z $comdec ]; then comdec=gzip fi [ -d /backup ] || mkdir /backup
case ?$comdec in gzip) tar zcf /backup/etc-`date +%F-%H-%S`.tar.gz /etc/* Retval=$? ;; bzip2) tar jcf /backup/etc-`date +%F-%H-%S`.tar.bz2 /etc/* Retval=$? ;; xz) tar Jcf /backup/etc-`date +%F-%H-%S`.tar.xz /etc/* Retval=$? ;; *) echo "usage: `basename $0` {[gzip|bzip2|xz]}" exit 6
? ? ;;
esac
?[ $Retval -eq 0] && echo "backup etc finished.($comdec)"
read命令
可以讀取鍵盤輸入數值到變量中
例如:
read a b
2 5
echo $a
2
1、echo -n 表示不換行,結合read一起使用。
2、read -p “內容” value
參數:
? ?-t :設置超時時間
? -p :設置輸出說明的內容
練習: 顯示一下菜單內容
m|M show memory?
d|D ?show disk
q|Q quit
2、如果用戶選擇了第一個選項,在顯示內存信息
? 如果選擇2,顯示磁盤掛載及使用情況
? 選擇3,退出,并顯示退出
?其他任何信息,均說明錯誤。
#!/bin/bash echo "(m|M) SHOW MEMORY" echo "d|D show disk" echo "q|Q quit" echo -n ?"please input (m|d|q)" && read choicecase $choice in m|M) free -m ;; d|D) df -lh ;; q|Q) echo "you are quit now" exit ?0 ;; *) echo "invalid input" exit 5 ;; esac ~ ? ? ?
安全上下文
? ? ? ?用戶執行訪問某一個文件的時候,涉及到兩個內容,第一就是使用的命令,第二就是被訪問對象,那么他的安全權限就分別由這兩個來決定,如果他沒有命令執行權限,被訪問對象無法執行,同樣如果被訪問對象沒有訪問權限,那么即使他有命令執行權限也是沒有用的。
通過passwd來理解特殊權限。
s:suid,set uid,屬主有s權限,意味著任何用戶在執行此程序的時候,其進程的屬主不在是發起人本身,而是這個程序的屬主。
chmod u+|- s ?/path/to/somefile
可以通過大小寫s來判斷這個suid是原來就有的還是后來賦予的,
s:原來有
S:后來加
s:sgid set gid,屬組有s權限,意味著執行此程序時,其進程的屬組不再是運行者所屬的基本組,而是程序的屬組。
chmod g+|- s /path/to/somefile
t:sticky,黏貼位,附加在other的權限上,表現為t,作用是只有文件所有者可以刪除,其他用戶不可以刪除。
chmod o+|- t /path/to/somefile?
chmod 3775 ?/tmp/test
練習:
1、復制/bin/cat為/tmp/cat
? ? ?cp /bin/cat /tmp/cat
2、復制/etc/rc.d/rc.sysinit為/tmp/hello
? ? ? cp /bin/rc.d/rc.sysinit /tmp/hello
3、設定helllo文件的其它用戶權限為無權限。
? ? ? ?chmod o-rwx /tmp/hello
4、切換至普通用戶,執行/tmp/cat,查看/tmp/hello,驗證是否可查。
? ? ? ?/tmp/cat /tmp/hello ? 無權限
5、以root用戶身份設定/tmp/cat 具有suid權限,然后用普通用戶,查看/tmp/cat,/tmp/hello,并驗證。
? ? ? ? chmod u+s /tmp/cat
? ? ? ? ?/tmp/cat /tmp/hello ? ?成功 ? 如果反過來只修改hello的suid,是不會執行成功的。
不同命令操作權限不同,結果也不同,總之要求編輯權限既要設置命令權限,也要設置文件權限最好。
練習二:
1、創建組magedu
? ? ?groupadd magedu
2、添加用戶hadoop和hive,均以magedu為額外組。
? ? ? useradd -g magedu hadoo
?
3、創建目錄/tmp/test,并設定其組為magedu。
? ? ?mkdir /tmp/test
? ? ?chgrp magedu /tmp/test
4、分別使用兩個普通用戶在/tmp/test目錄創建文件,看權限。
? ? ?su hadoo
? ? ?touch /tmp/test/123 ?不成功
5、設定/tmp/test目錄具有寫權限。
? ? ? chmod g+w /tmp/test
6、再次分別使用普通用戶創建文件,查看權限。如果能,查看文件屬組
? ? ? ?touch /tmp/test/123 不成功
7、設定/tmp/test的屬組具有SGID,再次創建并查看。并驗證刪除操作
? ? ? ?chmod g+s /tmp/test/123 成功
8、以root設定/tmp/test具有sticky,驗證刪除操作。
? ? ? ?rm /tmp/test/123 成功
? ? ? ?chmod o+t /tmp/test
? ? ? ?rm /tmp/test/123 ? 不成功,權限不足。
練習三:
1、復制/etc/issue為/tmp/issue
? ? ?cp /etc/issue /tmp/issue
2、修改/tmp/issue的權限為屬主讀寫執行,屬組讀寫,其他只讀,且具有suid
? ? ? chmod 4764 /tmp/issue
3、復制文件/etc/fstab為/tmp/fstab,修改/tmp/fstab的權限為屬主讀寫執行,屬組讀,其他只讀,且具有sgid和sticky。
? ? ? ?cp /etc/fstab /tmp/fstab
? ? ? ?chmod 3744 /tmp/fstab
FACL文件訪問控制列表
用于在原有的訪問控制機制之外增加一種文件訪問控制機制。由于普通用戶創建的文件不可以修改自身的權限(chmod)。就可以使用acl來限制其他用戶的訪問。
1、通過getfacl可以查看文件的權限。
getfacl /tmp/test/123
2、通過setfacl設置文件的訪問權限。
? -m, --modify=acl ? ? ? ?modify the current ACL(s) of file(s) ? ? ? ? ? ? ?
? setfacl -m u:username:mode /path/to/file ? ?#為用戶username設定具有mode的權限
? setfacl -m g:groupname:mode /path/to/file ? ? #為組groupname設定具有mode的權限
? -M, --modify-file=file ?read ACL entries to modify from file
? -x, --remove=acl ? ? ? ?remove entries from the ACL(s) of file(s)
? setfacl -x u:username /path/to/file ? ? ? ? ? #取消某一個用戶的acl權限。
? -X, --remove-file=file ?read ACL entries to remove from file
? -b, --remove-all ? ? ? ?remove all extended ACL entries
? -k, --remove-default ? ?remove the default ACL
? ? ? --set=acl ? ? ? ? ? set the ACL of file(s), replacing the current ACL
? ? ? --set-file=file ? ? read ACL entries to set from file
? ? ? --mask ? ? ? ? ? ? ?do recalculate the effective rights mask
? -n, --no-mask ? ? ? ? ? don't recalculate the effective rights mask
? -d, --default ? ? ? ? ? operations apply to the default ACL
? -R, --recursive ? ? ? ? recurse into subdirectories
? -L, --logical ? ? ? ? ? logical walk, follow symbolic links
? -P, --physical ? ? ? ? ?physical walk, do not follow symbolic links
? ? ? --restore=file ? ? ?restore ACLs (inverse of `getfacl -R')
? ? ? --test ? ? ? ? ? ? ?test mode (ACLs are not modified)
? -v, --version ? ? ? ? ? print version and exit
? -h, --help ? ? ? ? ? ? ?this help text
對于新加入的磁盤默認情況下是不支持acl功能的,需要通過在掛載的時候添加掛載選項-o acl才可以。
比如:
? ? ? ? ? ?mount -o acl /dev/sdb1 /mnt/sdb1
拒絕hive用戶對文件的任何訪問
setfacl -m u:hive:--- ?/tmp/test/123 ? 設置后即使o有權限也是不能訪問的。
bash編程之while和until
while 測試條件;
do
語句
done
條件滿足時就循環,直到條件不再滿足,就退出循環。
補充:
算數運算符
count=$[$count+$i] ?等于 ?count+=$i
sum=$[$sum+1] ?等于 ?let sum++
類似的 let sum-- 現加后引用
? ? ? ? ? ?let --sum ?先引用后加
計算100以內正整數的和
#!/bin/bash
sum=0
for i in {1..100};
do
sum+=$i
done
echo $sum
#!/bin/bash
sum=0
count=1
while [ $count -le 100];
do
sum+=$count
let count++
done
練習:如果用戶的id號是偶數,就顯示其名稱和shell,對所有用戶執行此操作。
while read line ;
do
uid=`echo $line |cut -d: -f 3`
if [ $[$uid%2 ] -eq 0 ];
then
?echo $line | cut -d: -f 1,7
fi
done < /etc/passwd
練習:轉換用戶輸入的字符為大寫,除了quit(遇見quit退出)
#!/bin/bash
String
read -p "A string:" String
while[?"$String"?!= 'quit' ]; ? ? ? #引號 用于帶空格的字符串轉換
do
echo $String |tr 'a-z' 'A-Z'
read -p "next(QUIT for quiting)" ?String
done
until 測試條件;
do
語句
done
條件不滿足就循環,滿足則不循環。
練習:每個10秒查看hadoo用戶是否登陸,如果登陸,顯示登陸并退出,否則,顯示時間,并說明未登陸。
until who |grep "hadoo" &>/dev/null ;
do
date
sleep 10
done
echo “hadoo is here”
程序在循環過程中不在執行循環體上面的內容了,所有需要繼續執行循環體外的內容,需要將其寫在循環體里面。
本文轉自 blackstome 51CTO博客,原文鏈接:http://blog.51cto.com/137783/1916955,如需轉載請自行聯系原作者
總結
- 上一篇: 基于Android官方AsyncList
- 下一篇: 通过rsync清除目录的shell脚本