Shell腳本應用及循環語句html
一.bash通配符:git
1. ?//任意的單個字符shell
2.*//0個或多個字符vim
3. [] //區間內的任意一個字符bash
4.; //分割命令,忽略前一個命令的執行結果,繼續執行後面的命令ide
5.& //後臺執行程序函數
6.&& //前面的命令執行成功,返回值是0,執行後面的命令。加密
7.|| //前面的命令執行失敗,返回值非0,執行後面的命令。spa
8. | //管道命令行
9.() //開啓子shell,執行裏面的命令
10.{} //裏面的命令在當前shell執行
11.> >> //輸出重定向
12.< << //輸入重定向
13.$ //定義變量
14.\ //轉義;命令的折行
15.`` //調用命令的執行結果;不能夠嵌套
16 .- //連字符;命令的選項的前導, - --
17. '' //強引用符號;屏蔽特殊字符
18."" //弱引用符號;`` $ \ 這3個符號屏蔽不了
19.: //表示空操做,返回值永遠是0;while循環
20. [:alnum:]//字母+數字
21[:alpha:] //字母
22[:lower:]//小寫字母
23[:upper:] //大寫字母
24[:digit:] //十進制數
25 [:punct:] //符號
26 [:space:]//空白字符(空格 「tab」)
27 [[:alnum:]] //任意的一個字母或數字[a-Z0-9]
28 [^[:alnum:]] //取反
[[:alnum:]!]
二. 變量
1.注意
(1)=的兩邊千萬不要有空格
(2)不要使用$做爲變量的名字
(3)變量名的長度--256個字符,區分大小寫
2.如何引用
(1)直接引用:
echo 命令
-e :啓用\(反斜線)控制字符(\t \n)的轉換
-n :取消換行符
[root@tx1 ~]# echo "123\t234"
123\t234
[root@tx1 ~]# echo -e "123\t234"
123 234
[root@tx1 ~]# echo -e "123\n234"
123
234
[root@tx1 ~]# echo -n "123\t234"
123\t234[root@tx1 ~]#
(2)間接引用
[root@tx1 ~]# a=b
[root@tx1 ~]# b=c
[root@tx1 ~]# echo $a
b
[root@tx1 ~]# echo ${!a}
c
(3)變量的做用域
@1在當前的shell裏,定義的變量叫作本地變量-局部變量。
@2全局變量-環境變量,export 把局部變量變成全局變量。只做用於子shell。
[root@tx1 ~]# x=123
[root@tx1 ~]# echo $x
123
[root@tx1 ~]# bash
[root@tx1 ~]# echo $x
[root@tx1 ~]# exit
exit
[root@tx1 ~]# export x
[root@tx1 ~]# bash
[root@tx1 ~]# echo $x
123
(4)查看定義的變量
@1.set 查看全部的變量
@2.env 查看全局變量
@3.unset 取消變量 unset+變量名
@4.設置變量爲只讀: readonly+變量名
(5)位置參數$
注:位置參數,從命令行傳遞給腳本,或者是傳遞給函數.或者賦職給一個變量.
$0 命令自己
$1 $2 ...... ${10}
$# 參數的個數
$* 全部的參數
$@ 全部的參數(須要被」 」 引用)
$$ 上一條命令的進程號
$? 上一條命令的返回結果
$_ 上一條命令的最後一個參數
$! 最後一個進入後臺的命令的進程號
$() 等同於``
$(()) 等同於$[] 作數學運算的,可是隻能算整數
(6)變量的置換
注:用來執行匹配或者是判斷變量是否存在。
@1.${變量名:-字符串}:若是變量是空的,那麼就返回字符串;不然返回變量的值
@2.${變量名:+字符串}:若是變量有值,那麼使用字符串替換變量;不然返回空值
@3.${變量名:=字符串}:若是變量沒有值,那麼就把字符串賦值給變量;不然返回變量的值
@4.${變量名:?提示信息}:若是變量沒有值,那麼返回提示信息
@1.
[root@tx1 ~]# echo $a
[root@tx1 ~]# echo ${a:-123}
123
[root@tx1 ~]# b=abc
[root@tx1 ~]# echo ${b:-123}
Abc
@2.
[root@tx1 ~]# echo ${a:+123}
[root@tx1 ~]# echo ${b:+123}
123
@3.
[root@tx1 ~]# echo $a
[root@tx1 ~]# echo $b
abc
[root@tx1 ~]# echo ${a:=123}
123
[root@tx1 ~]# echo $a
123
[root@tx1 ~]# echo ${b:=123}
abc
[root@tx1 ~]# echo $b
Abc
@4.
[root@tx1 ~]# unset a
[root@tx1 ~]# echo ${a:?}
bash: a: parameter null or not set
[root@tx1 ~]# echo ${a:?沒有設置變量}
bash: a: 沒有設置變量
(7)變量的匹配模式
#:從變量的值的頭部開始最小匹配,而後刪除
## :從變量的值的頭部開始最大匹配,而後刪除
% :從變量的值的尾部開始最小匹配,而後刪除
%% :從變量的值的尾部開始最大匹配,而後刪除
:num1:num2 :截取變量的值,num1是開始的位置,num2是截取出來幾位;0是第一個字符
@1.
[root@tx1 ~]# echo ${pth#*/}
usr/bin/local/bin/all
[root@tx1 ~]# echo ${pth##*/}
all
@2.
[root@tx1 ~]# echo ${pth%/*}
/usr/bin/local/bin
[root@tx1 ~]# echo ${pth%%/*}
[root@tx1 ~]#
@3.
[root@tx1 ~]# echo ${pth:0:6}
/usr/b
[root@tx1 ~]# echo ${pth:3:6}
r/bin/
三.If語句
1.單分支if語句.
if [ 條件表達式 ]; then
命令;...
fi
注:條件知足的時候,就會運行then後面的語句,不知足就直接退出判斷語句
2.雙分支if語句
if [ 條件表達式 ];then
命令;...
else
命令;...
fi
注:等條件知足的時候就會運行then後面的語句,條件不知足的時候就運行else後面的語句。
3.條件表達式(man test)
(1)字符串的判斷
str1 = str2 檢查str1與str2是否相同
str1 != str2 檢查str1與str2是否不一樣
str1 < str2 檢查str1是否小於str2
str1 > str2 檢查str1是否大於str2
-n str1 檢查str1的長度是否大於0
-z str1 檢查str1的長度是否爲0
=~:判斷左邊的字符串是否可以被右邊的模式所匹配,[[ "$opt1" =~ pattern ]], 注:判斷字符串的時候,字符串要用""包起來(更詳細的man test)
(2)整數的判斷
-eq 等於
-ge 大於等於
-gt 大於
-le 小於等於
-lt 小於
-ne 不等於
(3)文件的判斷
-b file 判斷是否存在且爲塊文件
-c file 判斷是否存在且爲字符文件
-d file 判斷是否存在且爲目錄文件
-e file 判斷文件是否存在
-f file 判斷文件是否存在且爲一個普通文件
-h file 判斷是否存在且爲符號連接
-r file 判斷是否存在且可讀
-s file 判斷是否存在且不爲空
-w file 判斷是否存在且可寫
-x file 判斷是否存在且可執行
-O file 判斷是否存在且用戶爲當前用戶
-G file 判斷是否存在且組爲當前組
(4)條件語句
與 -a
if [ 表達式1 -a 表達式2 ]
或 -o
if [ 表達式1 -o 表達式2 ]
非 !
if [ ! 表達式 ]
注
[[ 表達式1 && 表達式2 ]] == -a
[[ 表達式1 || 表達式2 ]] == -o
[[ ! 表達式 ]] == !
if 表達式
then
command
elif 表達式
then
command
elif 表達式
then
command
......
else
command
fi
(5)多重判斷
例1.
注:read -p
-t 超時時間 -t 3(秒)
-s 輸入沒有回顯,(密碼)
[root@tx1 ~]# vim tx1.sh
#!/bin/bash
#這是一個判斷文件類型的腳本
if [ -b /dev/hda1 ]
then
echo "塊設備"
fi
if [ -d /etc ]
then
echo "目錄"
fi
if [ -e /etc/passwd ]
then
echo "普通文件"
fi
[root@tx1 ~]# ./tx1.sh
塊設備
目錄
普通文件
例2
#!/bin/bash
#這是一個判斷用戶是否存在的腳本
read -p "請輸入一個用戶名:" uname
if [ "$uname" = "" ]
then
echo "error"
else
if grep "^\<$uname\>" /etc/passwd &> /dev/null
then
echo "這個用戶存在"
else
echo "這個用戶不存在"
fi
fi
例3(if的嵌套)
注:爲終端加密
[root@tx1 ~]# vim /etc/bashrc
read -p "請輸入用戶名:" uname
if [ "$uname" = "root" ]
then
read -p "請輸入密碼:" pass
if [ "$pass" = "123" ]
then
echo "welcome root"
else
exit 1
fi
else
exit 2
fi
打開一個新的終端後
請輸入用戶名:root
請輸入密碼:123
welcome root
[root@tx1 ~]#
例4
#!/bin/bash
# 使用雙重條件判斷用戶名和密碼
read -t 5 -p "username: " uname
read -s -p "password: " pass
echo
if [ "$uname" = "root" -a "$pass" = "123" ]
then
echo "welcome root"
else
echo "go out"
fi
例5
#!/bin/bash
#判斷一個用戶的類型
read -p "請輸入一個用戶名:" uname
id=`grep "^\<$uname\>" /etc/passwd | cut -d : -f 3 `
if [ "$uname" = "" ]
then
echo "error"
elif [ $id -ge 500 ]
then
echo "$uname 是普通用戶"
elif [ $id -lt 500 -a $id -ge 1 ]
then
echo "$uname 是系統用戶"
else
echo "$uname 是超級用戶"
fi
[root@tx1 ~]# ./tx5.sh
請輸入一個用戶名:root
root 是超級用戶
[root@tx1 ~]# ./tx5.sh
請輸入一個用戶名:tx
tx 是普通用戶
[root@tx1 ~]# ./tx5.sh
請輸入一個用戶名:bin
bin 是系統用戶
[root@tx1 ~]# ./tx5.sh
請輸入一個用戶名:
error
四.case 多分支判斷
語法:
case $變量 in
value1)
commands
;;
value2)
commands
;;
......
*)
commands
;;
esac
例1.
注:例如人的年齡: 0 嬰兒 ,1-9 幼兒,1-19 少年,20-29 青年,30-39 中年,40-老年
#!/bin/bash
# 判斷人的年齡段
read -p "請輸入一我的的年齡:" age
case $age in
0)
echo "嬰兒"
;;
[1-9])
echo "幼兒"
;;
1[0-9])
echo "少年"
;;
2[0-9])
echo "青年"
;;
3[0-9])
echo "中年"
;;
*)
echo "老年"
;;
esac
[root@tx1 ~]# ./t1.sh
請輸入一我的的年齡:3
幼兒
[root@tx1 ~]# ./t1.sh
請輸入一我的的年齡:67
老年
[root@tx1 ~]# ./t1.sh
請輸入一我的的年齡:20
青年
五.For循環
注:for循環 事先提供一個元素列表,然後,使用變量去遍歷此元素列表,每訪問一個元素,就執行一次循環體,直到元素訪問完畢
1.語法:
for 變量 in 變量列表
do
commands
done
例1. 用for循環輸出三個數
#!/bin/bash
for i in "$*"
do
echo $i
done
for j in "$@"
do
echo $j
done
[root@tx1 ~]# ./t3.sh 1 2 3
1 2 3
1
2
3
例2.把 /usr/share/doc/ 下全部的index.html複製到 /tmp/index/目錄下,/tmp/index/ 不肯定是否存在。
#!/bin/bash
if [ -d /tmp/index ]
then
num=1
for i in $(find /usr/share/doc -name index.html)
do
/bin/cp $i /tmp/index/index.html.$num
num=$(($num+1))
done
else
mkdir /tmp/index
num=1
for i in $(find /usr/share/doc -name index.html)
do
/bin/cp $i /tmp/index/index.html.$num
num=$(($num+1))
done
fi
六.While語句
語法:
while [ 表達式 ]
do
commands
更新表達式
done
表達式的做用:斷定循環是否執行。
表達式的返回值爲真, $?=0,執行命令
表達式的返回值是假的,結束循環。
: ;true 返回值永遠是真的。
例1.批量建立5個用戶
[root@tx1 ~]# cat t1.txt
tx1
tx2
tx3
tx4
tx5
[root@tx1 ~]# cat t6.sh
#!/bin/bash
while read line
do
uname=`echo $line`
useradd $uname
echo $uname | passwd $uname --stdin
done < /root/t1.txt
例2.信號捕捉
注:信號捕捉,trap,1 2 9 15 ,信號9是捕捉不了的。
#!/bin/bash
#信號捕捉
trap "echo 進程還在繼續" 1
while :
do
echo "hello"
sleep 3
done
[root@tx1 ~]# ps -a
PID TTY TIME CMD
18810 pts/2 00:00:00 bash
18813 pts/2 00:00:00 sleep
18814 pts/1 00:00:00 ps
[root@tx1 ~]# kill -1 18810
[root@tx1 ~]# ./t7.sh
hello
hello
hello
hello
進程還在繼續
hello
七.Until語句
語法:
until [ 表達式 ]
do
commands
更新表達式
done
表達式的做用:斷定循環是否執行。
表達式的返回值爲假的時候,執行循環,$? 非0
表達式的返回值爲真的時候,結束循環
例1.
#!/bin/sh
a=10;
until [[ $a -lt 0 ]];do
echo $a;
((a--));
done;
[root@tx1 ~]# ./t8.sh
10
9
8
7
6
5
4
3
2
1
0
八.shift,break和continue
例1
#!/bin/bash
until [ $# -eq 0 ]
do
echo $*
shift
done
[root@tx1 ~]# ./tt1.sh 1 2 3 4 5 6
1 2 3 4 5 6
2 3 4 5 6
3 4 5 6
4 5 6
5 6
6
例2.break跳出循環
#!/bin/bash
for i in `seq 1 2`
do
for j in `seq 1 3`
do
echo $j
if [ $j -eq 2 ]
then
break #跳出當前循環
fi
done
done
[root@tx1 ~]# ./tt2.sh
1
2
1
2
例3
#!/bin/bash
for i in `seq 1 10`
do
for j in `seq 1 3`
do
echo $j
if [ $j -eq 2 ]
then
break 2 #跳出第2層循環
fi
done
done
[root@tx1 ~]# ./tt3.sh
1
2
例4 (continue結束本次循環)
#!/bin/bash
for i in `seq 1 3`
do
for j in `seq 1 3`
do
if [ $j -eq 2 ]
then
continue #結束本次循環
fi
echo $j
done
done
[root@tx1 ~]# ./tt4.sh
1
3
1
3
1
3
例5
#!/bin/bash
for i in `seq 1 3`
do
for j in `seq 1 3`
do
if [ $j -eq 2 ]
then
continue 2 #結束第2層的本次循環
fi
echo $j
done
done
[root@tx1 ~]# ./tt5.sh
1
1
1