shell編程基礎(chǔ)(實(shí)用)及常用linux命令
變量的聲明
x=5
echo $x ---》輸出5
z=$x+6
echo $z ---》輸出5+6
變量的疊加:
x=123
y="$x"456
echo $y --->輸出123456
set可以查看系統(tǒng)下所有已經(jīng)生效的變量:包括系統(tǒng)的和認(rèn)為定義的變量。
set -u
echo $a ----->輸出空格或者空
如果提前輸入set -u
再輸入echo $a -----》調(diào)用未聲明的變量時會報錯。
unset 變量名 刪除變量
unset name 不加$,因為刪除的是變量而不是變量的值。
環(huán)境變量:
環(huán)境變量與用戶自定義變量的區(qū)別?
用戶自定義變量只在當(dāng)前的Shell中生效
環(huán)境變量在當(dāng)前Shell和這個Shell的所有子Shell中生效
環(huán)境變量是全局變量
用戶自定義變量是局部變量
在當(dāng)前shell中輸入bash進(jìn)入子shell
可以輸入pstree 查看進(jìn)程樹:就可以看到兩個bash,這說明有一個當(dāng)前shell,另一個是子shell。
從子shell退出到當(dāng)前shell,輸入exit
對系統(tǒng)生效的環(huán)境變量名和變量作用是固定的。
設(shè)置環(huán)境變量:
export 變量名 變量值
或者變量名 變量值
export 變量名
查看所有變量:
set:查看所有變量
env:查看環(huán)境變量
刪除環(huán)境變量:
unset 變量名
建議環(huán)境變量名字寫成大寫,主要是和命令區(qū)分,因為linux的命令都是小寫。
常用環(huán)境變量:
HOSTNAME:主機(jī)名
SHELL:當(dāng)前的shell
TERM:中斷環(huán)境
HISTSIZE:歷史命令條數(shù)
SSH_CLIENT:當(dāng)前操作環(huán)境是用ssh連接的,這里記錄客戶端ip
SSH_TTY:ssh連接的終端時pts/1
USER:當(dāng)前登錄的用戶
所有l(wèi)inux腳本必須以#!/bin/bash開頭。然后再去定義變量。
PATH環(huán)境變量:
PATH變量:系統(tǒng)查找命令的路徑
echo $PATH
#查看PATH環(huán)境變量
PATH="$PATH":/root/sh
#增加PATH變量的值
PS1環(huán)境變量:
PS1變量:命令提示符設(shè)置
\d:顯示日期,格式為“星期 月 日”
\H:顯示完整的主機(jī)名。如默認(rèn)主機(jī)名“l(fā)ocalhost.localdomain”
\t:顯示24小時制時間,格式為"HH:MM:SS"
\A:顯示24小時制時間,格式為"HH:MM"
\u:顯示當(dāng)前用戶名
\w:顯示當(dāng)前所在目錄的完整名稱
\W:顯示當(dāng)前所在目錄的最后一個目錄
\$:提示符。如果是root用戶會顯示提示符為"#",如果是普通用戶會顯示提示符為"$"
例如:[root@iZ2ze57xep3rm7w9t2l85cZ src]# PS1='[\u@\A \w]\$ '
執(zhí)行:[root@09:57 /usr/local/src]#
只對當(dāng)前生效,重啟恢復(fù)為:[root@iZ2ze57xep3rm7w9t2l85cZ logs]#
執(zhí)行:echo $PS1
輸出:[\u@\h \W]\$ 即為原來定義的PS1
ls \:換行,默認(rèn)還沒有輸入完。
語系變量:當(dāng)前語系查詢。
locale:查看語系。
輸入:locale
輸出:[root@09:57 /usr/local/src]# locale
LANG=en_US.UTF-8 :美系語言版本。
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
統(tǒng)計分支大小命令:df -h
輸出:[root@iZ2ze57xep3rm7w9t2l85cZ src] df -h
Filesystem Size Used Avail Use% Mounted on :如果是中文語系,這一行會有中文顯示。
/dev/vda1 40G 4.8G 33G 13% /
devtmpfs 486M 0 486M 0% /dev
tmpfs 496M 0 496M 0% /dev/shm
tmpfs 496M 452K 496M 1% /run
tmpfs 496M 0 496M 0% /sys/fs/cgroup
tmpfs 100M 0 100M 0% /run/user/0
LANG:定義系統(tǒng)主語系的變量
查看系統(tǒng)當(dāng)前語系:echo $LANG
查看Linux支持的所有語系:locale -a | more
LC_ALL:定義整體語系的變量
cat /etc/sysconfig/i18n :Linux一切皆文件,放在文件里的即為永久有效的。這里的語系即為當(dāng)前l(fā)inux語系,且重啟或者下次開機(jī)仍為這里配置的語系。
位置參數(shù)變量:
$n:n為數(shù)字,$0代表命令本身,$1-$9代表第一到第九個參數(shù),十以上的參數(shù)需要用大括號包括如${10}
例子1:
#!/bin/bash
num1=$1
num2=$2
sum=$(($num1+$num2)) #num1的值時$1,num2的值是$2
echo $sum :打印變量sum的值
執(zhí)行去賦予權(quán)限:chmod 755 **.sh
1.文件所有者可讀可寫可執(zhí)行 6:可讀可寫
2.與文件所有者同屬一個用戶組的其他用戶可讀可執(zhí)行
3.其它用戶組可讀可執(zhí)行
執(zhí)行:./**.sh 10 11
輸出:21
以上適合開發(fā)者使用,不適合第三方使用。
$*:這個變量代表命令行中所有的參數(shù),$*把所有的參數(shù)看成一個整體
$@:這個變量也代表命令行中所有的參數(shù),不過$@把每個參數(shù)區(qū)分對待
$#:這個變量代表命令行中所有參數(shù)的個數(shù)
for x in "$*"
do
echo $x
done
for y in "$@"
do
echo $y
done
[root@iZ2ze57xep3rm7w9t2l85cZ local]# chmod 755 zhaopeng.sh
[root@iZ2ze57xep3rm7w9t2l85cZ local]# ./zhaopeng.sh 1 2 3
1 2 3
1
2
3
假設(shè)$*有四個數(shù)字,那么把四個數(shù)字看成一個整體,所以只有一次循環(huán)
而$@會有4次循環(huán)。
預(yù)定義變量:
$?:最后一次執(zhí)行的命令的返回狀態(tài)。如果這個變量的值為0,證明上一個命令正確執(zhí)行;如果這個變量的值為非0(具體是哪個數(shù),由命令自己來決定),則證明上一個命令執(zhí)行不正確了。
$$:當(dāng)前進(jìn)程的進(jìn)程號(PID)
$!:后臺運(yùn)行的最后一個進(jìn)程的進(jìn)程號(PID)
接受鍵盤輸入:read
read [選項] [變量名]
選項:
-p "提示信息":在等待read輸入時,輸出提示信息
-t 秒數(shù):read命令會一直等待用戶輸入,使用此選項可以指定等待時間
-n 字符數(shù):read命令只接受指定的字符數(shù),就會執(zhí)行
-s :隱藏輸入的數(shù)據(jù),適用于機(jī)密信息的輸入
寫一個腳本read.sh:
#!/bin/bash
read -p "please input your name: " -t 30 name
echo $name
執(zhí)行時輸出:please input your name: 123
123
如果等待30秒還沒有輸入,系統(tǒng)自動結(jié)束腳本命令。
read -p "please input your passwd: " -s password
echo -e "\n" :換行
echo $password
執(zhí)行時輸出:在輸入時不會顯示密碼明文。
read -p "please input your sex [M/F]: " -n 1 sex :只允許輸入一個字符。M或者N
echo -e "\n" :換行
echo $sex
按照文件類型進(jìn)行判斷
-b 文件:判斷該文件是否存在,并且是否為塊設(shè)備文件(是塊設(shè)備文件為真)
-c 文件:判斷該文件是否存在,并且是否為字符設(shè)備文件(是字符設(shè)備文件為真)
-d 文件:判斷該文件是否存在,并且是否為目錄文件(是目錄為真) 常用
-e 文件:判斷該文件是否存在(存在為真) 常用
-f 文件:判斷該文件是否存在,并且是否為普通文件(是普通文件為真) 常用
-L 文件:判斷該文件是否存在,并且是否為符號鏈接文件(是符號鏈接文件為真)
-p 文件:判斷改文件是否存在,并且是否為管道文件(是管道文件為真)
-s 文件:判斷該文件是否存在,并且是否為非空(非空為真)
-S 文件:判斷該文件是否存在,并且是否為套接字文件(是套接字文件為真)
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -e zhaopeng.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
0 為真,存在
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -e zhaopeng.sh ] && echo yes || echo no
yes
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -e zhaopeng1.sh ] && echo yes || echo no
no
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -f zhaopeng.sh ] && echo yes || echo no
yes
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -d zhaopeng.sh ] && echo yes || echo no
no
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -d etc ] && echo yes || echo no
yes
按照文件權(quán)限進(jìn)行判斷:
-r 文件:判斷該文件是否存在,并且是否該文件擁有讀權(quán)限(有讀權(quán)限為真)
-w 文件:判斷該文件是否存在,并且是否該文件擁有寫權(quán)限(有寫權(quán)限為真)
-x 文件:判斷該文件是否存在,并且是否該文件擁有執(zhí)行權(quán)限(有執(zhí)行權(quán)限為真)
-u 文件:判斷該文件是否存在,并且是否該文件擁有SUID權(quán)限(有SUID權(quán)限為真)
-g 文件:判斷該文件是否存在,并且是否該文件擁有SGID權(quán)限(有SGID權(quán)限為真)
-k 文件:判斷該文件是否存在,并且是否該文件擁有SBit權(quán)限(有SBit權(quán)限為真)
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -w zhaopeng.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
0
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -r zhaopeng.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
0
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -x zhaopeng.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
0
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -u zhaopeng.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
1
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -g zhaopeng.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
1
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -k zhaopeng.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
1
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -w zhaopeng1.sh]
-bash: [: missing `]'
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -w zhaopeng1.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
兩個文件之間進(jìn)行比較
文件1 -nt 文件2:判斷文件1的修改時間是否比文件2的新(如果新則為真)
文件1 -ot 文件2:判斷文件1的修改時間是否比文件2的舊(如果舊則為真)
文件1 -ef 文件2:判斷文件1是否和文件2的lnode號一致,可以理解為兩個文件是否為同一個文件。
這個判斷用于判斷硬鏈接是很好的方法
兩個整數(shù)之間比較:
整數(shù)1 -eq 整數(shù)2:判斷整數(shù)1是否和整數(shù)2相等(相等為真)
整數(shù)1 -ne 整數(shù)2:判斷整數(shù)1是否和整數(shù)2不相等(不相等為真)
整數(shù)1 -gt 整數(shù)2:判斷整數(shù)1是否大于整數(shù)2(大于為真)
整數(shù)1 -lt 整數(shù)2:判斷整數(shù)1是否小于整數(shù)2(小于為真)
整數(shù)1 -ge 整數(shù)2:判斷整數(shù)1是否大于等于整數(shù)2(大于等于為真)
整數(shù)1 -le 整數(shù)2:判斷整數(shù)1是否小于等于整數(shù)2(小于等于為真)
字符串的判斷:
-z 字符串:判斷字符串是否為空(為空返回真)
-n 字符串:判斷字符串是否為非空(非空返回真)
字符串1==字符串2:判斷字符串1是否和字符串2相等(相等返回真)
字符串1!=字符串2:判斷字符串1是否和字符串2不相等(不相等返回真)
[root@iZ2ze57xep3rm7w9t2l85cZ local]# name=fengjie
[root@iZ2ze57xep3rm7w9t2l85cZ local]# name2=jjj
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ "$name" == "$name2" ] && echo yes || echo no
no
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ "$name" != "$name2" ] && echo yes || echo no
yes
多重條件判斷:
判斷1 -a 判斷2:邏輯與,判斷1和判斷2都成立,最終的結(jié)果才為真
判斷1 -o 判斷2:邏輯或,判斷1和判斷2有一個成立,最終的結(jié)果就為真
!判斷:邏輯非,使原始的判斷式取反
以上內(nèi)容[]即為test命令,但是一般常用的都是[]
流程控制語句:
單分支if條件語句
if [ 條件判斷式 ];then
程序
fi
或者:
if[ 條件判斷式 ]
then
程序
fi
單分支條件語句需要注意幾個點(diǎn)
1、if語句使用fi結(jié)尾,和一般語言使用大括號結(jié)尾不同
2、[ 條件判斷式 ]就是使用test命令判斷,所以中括號和條件判斷式之間必須有空格
3、then后面跟符合條件之后執(zhí)行的程序,可以放在[]之后,用";"分割。也可以換行寫入,就不需要";"了
例子1:判斷登陸的用戶是否root
查看當(dāng)前用戶:whoami后者env 下的USER即為當(dāng)前用戶
env | grep "USER" :查看的是帶有USER的一行數(shù)據(jù)。
cut -d "=" -f 2 :以等號為分隔符,截取第二個字符。-d用來定義分隔符,默認(rèn)為tab鍵,-f表示需要取得哪個字段
[root@iZ2ze57xep3rm7w9t2l85cZ local]# more testzhao.sh
#!/bin/bash
#查出當(dāng)前用戶,截取到當(dāng)前用戶,將當(dāng)前用戶名賦予test
test=$(env | grep "USER" | cut -d "=" -f 2)
#獲取到test的值和root進(jìn)行字符串匹配,如果相等,輸出dangqian yonghu shi root
if [ "$test" == root ]
then
echo "dangqian yonghu shi root"
fi
[root@iZ2ze57xep3rm7w9t2l85cZ local]# ./testzhao.sh
dangqian yonghu shi root
判斷分區(qū)使用率
#查看系統(tǒng)分支:
[root@iZ2ze57xep3rm7w9t2l85cZ ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 4.8G 33G 13% /
devtmpfs 486M 0 486M 0% /dev
tmpfs 496M 0 496M 0% /dev/shm
tmpfs 496M 484K 496M 1% /run
tmpfs 496M 0 496M 0% /sys/fs/cgroup
tmpfs 100M 0 100M 0% /run/user/0
#查看根分支
[root@iZ2ze57xep3rm7w9t2l85cZ ~]# df -h | grep "vda1"
/dev/vda1 40G 4.8G 33G 13% /
#輸出第五列
[root@iZ2ze57xep3rm7w9t2l85cZ ~]# df -h | grep "vda1" | awk '{print $5}'
13%
#輸出第五列的同時以%為分隔符,截取第一個字符
[root@iZ2ze57xep3rm7w9t2l85cZ ~]# df -h | grep "vda1" | awk '{print $5}' | cut -d "%" -f 1
13
#!/bin/bash
#截取根分支的使用率,以%分割
rate=$(df -h | grep "vda1" | awk '{print $5}' | cut -d "%" -f 1)
#判斷rate的值小于80則輸出genmulu。。。。否則輸出busuanda。
if [ "$rate" -le 80 ]
then
echo "genmulu shiyong guo da"
else
echo "busuanda"
fi
雙分支if條件語句
if [ 條件判斷式 ]
then
條件成立時,執(zhí)行的程序
else
條件不成立時,執(zhí)行的另一個程序
fi
例子:判斷輸入的是不是目錄
#!/bin/bash
read -p "請輸入一個目錄:" -t 30 dir
if [ -d "$dir" ] #判斷輸入的信息是否存在并且是否是一個目錄文件
then
echo "您輸入的是一個目錄"
else
echo "nononono"
fi
判斷apache服務(wù)是否運(yùn)行 ps aux :查看所有正在運(yùn)行的程序
#!/bin/bash
tomzhao=$(ps -ef | grep tomcat | grep -v grep)
if [ -n "$tomzhao" ]
then echo "$(date) tomcat正在運(yùn)行......" >> /usr/local/zhaopeng.log
else
/usr/local/tomcat/apache-tomcat-8.5.45/bin/startup.sh & > /dev/null
echo "$(date) tomcat已經(jīng)重啟......" >> /usr/local/zhaopengerr.log
fi
多分支if條件語句
if[ 條件判斷式1 ]
then
當(dāng)條件判斷式1成立時,執(zhí)行程序1
elif [ 條件判斷式2 ]
then
當(dāng)條件判斷式2成立時,執(zhí)行程序2
...省略更多條件...
else
當(dāng)所有條件都不成立時,最后執(zhí)行此程序
fi
seq 1 10:用于產(chǎn)生從某個數(shù)到另外一個數(shù)之間的所有整數(shù)
例一:
# seq 1 10
結(jié)果是1 2 3 4 5 6 7 8 9 10
[root@iZ2ze57xep3rm7w9t2l85cZ local]# for i in $(seq 1 10)
> do
> echo i=$(seq 1 10)
> done
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
[root@iZ2ze57xep3rm7w9t2l85cZ local]# for i in $(seq 1 10)
> do
> echo $i
> done
1
2
3
4
5
6
7
8
9
10
多分支case條件語句:
case語句和if elif...else語句一樣都是多分支條件語句,不過和if多分支條件語句不同的是,case語句只能
判斷一種條件關(guān)系,而if語句可以判斷多種條件關(guān)系。
case $變量名 in
“值1”)
如果變量的值等于值1,則執(zhí)行程序1
;;
“值2”)
如果變量的值等于值2,則執(zhí)行程序2
;;
...省略其他分支...
*)
如果變量的值不是以上的值,則執(zhí)行此程序
;;
esac
例子:輸入yes或者no,來判斷輸入的是否符合yes或者no或者輸入錯誤
read -p "please choose yes/no:" -t 30 cho
case $cho in
"yes")
echo "you choosed yes!you are right!"
;;
"no")
echo "you choosed no!you are right!"
;;
*)
echo "you are wrong!!"
;;
esac
解壓多個文件,用for循環(huán)實(shí)現(xiàn):
#!/bin/bash
#進(jìn)入到對應(yīng)要操作的目錄
cd /usr/local/testdir
#查看.tar.gz結(jié)尾的壓縮文件數(shù)量并記錄到ll.log中
ls *.tar.gz > ll.log
#查看ll.log中的壓縮文件個數(shù)和名稱并循環(huán)賦值給i
for i in $(cat ll.log)
do
#執(zhí)行解壓縮操作(后臺執(zhí)行,不打印日志和信息
tar -zxf $i & > /dev/null
done
#刪除掉臨時日志文件ll.log
rm -rf /usr/local/testdir/ll.log
while循環(huán):
while循環(huán)是不定循環(huán),也稱作條件循環(huán)。只要條件判斷式成立,循環(huán)就會一直繼續(xù),知道條件判斷式不成立,循環(huán)才會停止。這就和for的固定循環(huán)不太一樣了。
while [ 條件判斷式 ]
do
程序
done
ctrl鍵的妙用:
ctrl+a:回到當(dāng)前輸入/便在行首插入字符,不用按住方向鍵了。
ctrl+e:與上個組合相反,回到行尾。
ctrl+l:清空當(dāng)前的終端界面,效果等同于clear命令。
ctrl+u:清空當(dāng)前輸入行的所有輸入。假設(shè)你輸入了aa bb,按下這個組合鍵,aa bb就被刪掉了。
ctrl+y:就是把ctrl+u刪除的字符串粘貼回來。
ctrl+r:歷史命令搜索。按下ctrl+r后,會搜索包含你輸入的字符串的命令。
ctrl+c:終止當(dāng)前終端正在運(yùn)行的程序。
ctrl+d:推送當(dāng)前終端。
ctrl+z:把終端當(dāng)前正在運(yùn)行的程序放到后臺運(yùn)行。

浙公網(wǎng)安備 33010602011771號