bash中變量的種類
局部變量:生效范圍為當(dāng)前shell進(jìn)程,對當(dāng)前shell之外的其它shell進(jìn)程幅狮,包括當(dāng)前shell的子shell進(jìn)程均無效
環(huán)境變量:生效范圍為當(dāng)前shell進(jìn)程及其子進(jìn)程
本地變量:生效范圍為當(dāng)前shell進(jìn)程中某代碼片段音诈,通常指函數(shù)
位置變量:$1畦徘,$2芦劣,...來表示院尔,用于腳本中調(diào)用命令行傳遞的參數(shù)
特殊變量:$?, $0, $*, $@, $#,$$
[root@centos7 ~]# echo $$
4766
[root@centos7 ~]# echo $PPID
4760
[root@centos7 ~]# pstree -p |grep sshd
|-sshd(1066)-+-sshd(1749)---bash(1764)---vim(8386)
| `-sshd(4760)---bash(4766)-+-grep(8672)
局部變量
變量賦值:name=value
變量引用:name="root" name="$USER" name='command' name=$(command)
顯示已定義的所有變量:set
刪除變量:unset name
[root@centos6 ~]# a=root
[root@centos6 ~]# echo "$a" '$a'
root $a
環(huán)境變量
變量賦值:export name=value declare -x name=value
變量引用:$name ${name}
顯示所有環(huán)境變量:env export
刪除變量:unset name
只讀和位置變量
只讀變量
只能聲明,但不能修改和刪除魁亦,只對當(dāng)前登錄用戶有效,退出重進(jìn)就失效了
聲明只讀變量: readonly name
查看只讀變量:readonly -p
位置變量
在腳本代碼中調(diào)用命令行傳遞給腳本的參數(shù)
$1, $2, ...:對應(yīng)第1羔挡、第2等參數(shù)洁奈,shift [n]換位置
$0:位置變量中命令本身
$*:位置變量中傳遞給腳本的所有參數(shù),全部參數(shù)合為一個(gè)字符串
$@:位置變量中傳遞給腳本的所有參數(shù)绞灼,每個(gè)參數(shù)為獨(dú)立字符串
$#:位置變量中傳遞給腳本的參數(shù)的個(gè)數(shù)
set --:清空所有位置變量
[root@centos6 app]# ./a.sh {0..9}
$1 is:0
$2 is:1
$3 is:2
$4 is:3
$0 is:./a.sh
$10 is:9
$* is:0 1 2 3 4 5 6 7 8 9
$# is:10
()和{}
()的作用:在當(dāng)前shell下開啟一個(gè)新空間利术,shell進(jìn)程號未變,小括號里面的變量不影響外面低矮,外面的變量可以影響小括號里面印叁。 加小括號的意思是執(zhí)行一次小括號里面的命令就完事了,所以將來編腳本的時(shí)候如果需要用到一次性的任務(wù),不想影響周邊的環(huán)境轮蜕,就可以用小括號寫法
{}的作用:不開啟子shell昨悼,將影響當(dāng)前的shell環(huán)境,注意{}的寫法跃洛,前后有空格率触,且最后有分號
退出狀態(tài)
進(jìn)程使用退出狀態(tài)來報(bào)告成功或失敗
0代表成功,非0代表失敗
$?:上一次命令執(zhí)行的情況
exit #:自定義退出狀態(tài)碼汇竭,如果未給腳本指定退出狀態(tài)碼葱蝗,整個(gè)腳本的退出狀態(tài)碼取決于腳本中執(zhí)行的最后一條命令的狀態(tài)碼
[root@centos6 app]# ping -c1 -W1 172.18.0.1 &> /dev/null ;echo $?
0
[root@centos6 app]# ping -c1 -W1 172.18.0.300 &> /dev/null ;echo $?
2
[root@centos6 app]# ping -c1 -W1 172.18.0.200 &> /dev/null ;echo $?
1
bash中運(yùn)算和賦值
算數(shù)運(yùn)算
bash中的算數(shù)運(yùn)算:+,-细燎,两曼,/,%(取余數(shù))玻驻,*(乘方)
let var=算數(shù)表達(dá)式
var=$[算數(shù)表達(dá)式]
var=$((算術(shù)表達(dá)式))
declare –i var=數(shù)值
echo '算術(shù)表達(dá)式' |bc
$RANDOM(0-32767):echo $[$RANDOM%50]
邏輯運(yùn)算
與(且):第一個(gè)為假悼凑,結(jié)果必定為假;第一個(gè)為真击狮,第二個(gè)必須要參與運(yùn)算
或:第一個(gè)為真佛析,結(jié)果必定為真;第一個(gè)為假彪蓬,第二個(gè)必須參與運(yùn)算
非:!
異或^:異或的兩個(gè)值寸莫,相同為假,不同為真
賦值
var+=1:自加1
var++:自加1
var-=1:自減1
var--:自減1
read
從stdin中讀取值档冬,給變量賦值膘茎,stdin多余的內(nèi)容會都賦值給最后一個(gè)變量,常用選項(xiàng):
- -p:指定要顯示的提示
- -s:靜默輸入酷誓,一般用于密碼
- -n #:指定輸入的字符長度
- -d 'string':指定輸入結(jié)束符
- -t number:指定超時(shí)時(shí)間披坏,單位為秒
[root@centos6 ~]# read a b c
nihao helloworld ccc ddd eee
[root@centos6 ~]# echo "$a|$b|$c"
nihao|helloworld|ccc ddd eee
[root@centos6 ~]# read -p '請輸出密碼:' passwd
請輸出密碼:centos
[root@centos6 ~]# echo $passwd
centos
bash中常用的測試命令
條件測試
每條命令系統(tǒng)都會返回執(zhí)行布爾值,以便用在條件性執(zhí)行中:0表示真盐数,1表示假
測試命令:注意方括號首尾都有空格
test experssion
[ experssion ]
[[ experssion ]]
條件性的執(zhí)行操作符
&&:代表?xiàng)l件性的且
||:代表?xiàng)l件性的或
[root@centos6 ~]# ping -c1 -W2 172.18.0.100 &> /dev/null && echo "Succcess" || echo "False"
Succcess
[root@centos6 ~]# ping -c1 -W2 172.18.0.200 &> /dev/null && echo "Succcess" || echo "False"
False
[root@centos6 ~]# ping -c1 -W2 172.18.0.300 &> /dev/null && echo "Succcess" || echo "False"
False
數(shù)值測試
-gt:是否大于
-ge:是否大于等于
-eq:是否等于
-ne:是否不等于
-lt:是否小于
-le:是否小于等于
字符串測試
==:是否等于
>:ascii是否大于ascii
<:是否小于
!=:是否不等于
=~:左側(cè)是否包含右側(cè)棒拂,此表達(dá)式一般用于[[ ]]中,支持?jǐn)U展的正則表達(dá)式
-z “string”:字符串是否為空玫氢,空為真帚屉,不空為假
-n “string”:字符串是否不為空,不空為真漾峡,空為假
文件測試
-a file:同-e
-e file:是否存在攻旦,存在為真,不存在為假
-b file:是否存在且為塊設(shè)備文件
-c file:是否存在且為字符設(shè)備文件
-d file:是否存在且為目錄文件
-f file:是否存在且為普通文件
-h/-L file:是否存在且為符號鏈接文件
-p file:是否存在且為命名管道文件
-S file:是否存在且為套接字文件
文件權(quán)限測試
-r file:是否存在且可讀
-w file:是否存在且可寫
-x file:是否存在且可執(zhí)行
-u file:是否存在且擁有suid權(quán)限
-g file:是否存在且擁有sgid權(quán)限
-k file:是否存在且擁有sticky權(quán)限
文件屬性測試
單文件測試
-s file:是否存在且非空
-t file:是否在某終端已經(jīng)打開
-N file:文件自從上一次被讀取之后是否被修改過
-O:當(dāng)前登錄用戶是否為文件屬主
-G:當(dāng)前登錄用戶是否為文件屬組
雙目測試
file1 -ef file2:file1是否是file2的硬鏈接
file1 -nt file2:file1是否新于file2(mtime)
file1 -ot file2:file1是否舊于file2
組合測試條件
[root@centos6 ~]# [ -f /bin/cat ] && echo "Success" || echo "False"
Success
[root@centos6 ~]# [ -g /bin/cat ] && echo "Success" || echo "False"
False
bash中防止擴(kuò)展
\:轉(zhuǎn)義符生逸,使隨后的字符按照原意解釋
':單引號牢屋,強(qiáng)引用且预,防止所有擴(kuò)展
":雙引號,弱引用烙无,防止所有擴(kuò)展锋谐,以下除外($:變量擴(kuò)展、`:命令替換皱炉、 \:禁止單個(gè)字符擴(kuò)展怀估、!:歷史命令替換)
bash的配置文件
全局配置
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
個(gè)人配置
~/.bash_profile
~/.bashrc
配置文件讀取順序
交互式登錄:/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile--> ~/.bashrc--> /etc/bashrc
非交互式登錄::~/.bashrc--> /etc/bashrc--> /etc/profile.d/*.sh
編輯配置文件生效
重新啟動shell進(jìn)程
./source filename:直接重新讀取配置文件
~/.bash_logout
在退出登錄shell時(shí)執(zhí)行,可以通過編輯此文件實(shí)現(xiàn)退出時(shí)自動備份和清理臨時(shí)文件
練習(xí)
-
編寫腳本/root/bin/createscripts.sh合搅,輸入createscripts.sh /path/newsh.sh多搀,則會在指定路徑生成腳本文件,并涵蓋注釋信息
#!/bin/bash touch $1 echo "# -----------------------------------" >> $1 echo "# Filename: `basename $1`" >> $1 echo "# Revision: 1.0" >> $1 echo "# Date: `date "+%F"`" >> $1 echo "# Author: fanjie" >> $1 echo "# Email: 361163404@qq.com" >> $1 echo "# Website: www.fanjie.com" >> $1 echo "# Description: " >> $1 echo "# -----------------------------------" >> $1 echo "# Copyright: 2018 fan" >> $1 echo "# License: GPl" >> $1 vim $1 chmod +x $1
-
編寫腳本/root/bin/systeminfo.sh灾部,顯示當(dāng)前主機(jī)系統(tǒng)信息康铭,包括主機(jī)名、IPV4地址赌髓、操作系統(tǒng)版本从藤、內(nèi)核版本、CPU型號锁蠕、內(nèi)存大小夷野、硬盤大小
#!/bin/bash echo "當(dāng)前主機(jī)系統(tǒng)信息如下: " echo "主機(jī)名: `hostname` " echo "IPV4地址: `ifconfig ens33|grep "\(inet\)[[:blank:]]"|tr -s ' '|cut -d' ' -f3`" echo "操作系統(tǒng)版本: `cat /etc/redhat-release |cut -d' ' -f1-4`" echo "內(nèi)核版本: `uname -r`" echo "CPU型號: `lscpu|grep "^\(Model \)"|tr -s ' '|cut -d' ' -f3-8`" echo "內(nèi)存型號: `free -m|grep "\(Mem\)"|tr -s ' '|cut -d' ' -f2` MB" echo "硬盤大小: `fdisk -l /dev/sda |grep "^\(Disk /dev/sda\)"|cut -d' ' -f3` GB"
-
編寫腳本/root/bin/backup.sh,可實(shí)現(xiàn)將/etc/目錄備份到/root/etcYYYY-mm-dd中
#!/bin/bash cp -a /etc/ /root/ mv /root/etc /root/etc`date +"%F"`
-
編寫腳本/root/bin/disk.sh,顯示當(dāng)前硬盤分區(qū)中空間利用率最大的值
#!/bin/bash df |tr -s ' ' %|sort -t% -k5 -nr|head -1|cut -d% -f5
-
編寫腳本/root/bin/links.sh,顯示正連接本主機(jī)的每個(gè)遠(yuǎn)程主機(jī)的IPv4地址和連接數(shù)荣倾,并按連接數(shù)從大到小排序
#!/bin/bash cat /var/log/httpd/access_log|cut -d- -f1|sort|uniq -c|sort -t' ' -k1 -nr
-
編寫腳本/root/bin/sumid.sh悯搔,計(jì)算/etc/passwd文件中的第10個(gè)用戶和第20用戶的UID之和
#!/bin/bash UID10=`cat -n /etc/passwd|grep "^\([[:space:]]*10\)"|cut -d: -f3` UID20=`cat -n /etc/passwd|grep "^\([[:space:]]*20\)"|cut -d: -f3` echo $UID10+$UID20 |bc
-
編寫腳本/root/bin/sumid.sh,計(jì)算/etc/passwd文件中的第x用戶和第y用戶的ID之和舌仍,xy為參數(shù)指定
#!/bin/bash UID1=`cat -n /etc/passwd|grep "^\([[:space:]]*$1\)"|cut -d: -f3` UID2=`cat -n /etc/passwd|grep "^\([[:space:]]*$2\)"|cut -d: -f3` echo $UID1+$UID2 |bc
-
編寫腳本/root/bin/sumspace.sh妒貌,傳遞兩個(gè)文件路徑作為參數(shù)給腳本,計(jì)算這兩個(gè)文件中所有空白行之和
#!/bin/bash space1=`cat $1 |grep "^[[:space:]]*$"|wc -l` space2=`cat $2 |grep "^[[:space:]]*$"|wc -l` echo $space1+$space2 |bc
-
編寫腳本/root/bin/sumfile.sh,統(tǒng)計(jì)/etc, /var, /usr目錄中共有多少個(gè)一級子目錄和文件
#!/bin/bash etc=$[$(ls -l /etc/ |wc -l)-1] var=$[$(ls -l /var/ |wc -l)-1] usr=$[$(ls -l /usr/ |wc -l)-1] echo $[$etc+$var+$usr]
-
編寫腳本/root/bin/hostping.sh铸豁,接受一個(gè)主機(jī)的IPv4地址做為參數(shù)灌曙,測試是否可連通。如果能ping通节芥,則提示用戶“該IP地址可訪問”在刺;如果不可ping通,則提示用戶“該IP地址不可訪問”
#!/bin/bash ping -c1 -W1 $1 &> /dev/null && echo "該IP可訪問" || echo "該IP不>可訪問"
-
對以上對該腳本進(jìn)行升級头镊,可以判斷ip地址的合法型增炭,如果不合法,直接提示用戶"IP地址不合法"并退出
#!/bin/bash
-
編寫腳本/root/bin/checkdisk.sh拧晕,檢查磁盤分區(qū)空間和inode使用率,如果超過80%梅垄,就發(fā)廣播警告空間將滿
#!/bin/bash use1=`df |tr -s ' ' %|sort -t% -k5 -nr|head -1|cut -d% -f5` [ $use1 -gt 80 ] && echo "磁盤可用空間超過80%" use2=`df -i|tr -s ' ' %|sort -t% -k5 -nr|head -1|cut -d% -f5` [ $use2 -gt 80 ] && echo "inode可用空間超過80%"
-
編寫腳本/bin/per.sh,判斷當(dāng)前用戶對指定的參數(shù)文件厂捞,是否不可讀并且不可寫
#!/bin/bash [ !-r $1 ] && [ !-w $1 ] && echo "this user can't rw"
-
編寫腳本/root/bin/excute.sh 输玷,判斷參數(shù)文件是否為sh后綴的普通文件,如果是靡馁,添加所有人可執(zhí)行權(quán)限欲鹏,否則提示用戶非腳本文件
#!/bin/bash echo $1 | grep "\.sh$" && chmod +x $1 || echo "非腳本文件"
-
讓所有用戶的PATH環(huán)境變量的值多出一個(gè)路徑,例如:/usr/local/apache/bin
export PATH=$PATH:/usr/local/apache/bin 將上述文件寫入/etc/profile臭墨,/etc/profile.d/*.sh赔嚎,/etc/bashrc
-
用戶root登錄時(shí),將命令指示符變成紅色胧弛,并自動啟用如下別名:rm=‘rm –i’
cdnet=‘cd /etc/sysconfig/network-scripts/’
editnet=‘vim /etc/sysconfig/network-scripts/ifcfg-eth0’
editnet=‘vim /etc/sysconfig/network-scripts/ifcfg-eno16777736 或 ifcfg-ens33 ’ (如果系統(tǒng)是CentOS7)PS1='\[\e[1;31m\][\u@\h \W]\$\[\e[0m\]' 將上述文件寫入/root/.bashrc或/root/.bash_profile
-
任意用戶登錄系統(tǒng)時(shí)尤误,顯示紅色字體的警示提醒信息“Hi,dangerous!”
echo -e "\033[31mHi,dangerous\!\033[0m" 將上述文件寫入/etc/profile结缚,/etc/profile.d/*.sh损晤,/etc/bashrc
-
編寫用戶的環(huán)境初始化腳本reset.sh,包括別名红竭,登錄提示符尤勋,vim的設(shè)置,環(huán)境變量等
#!/bin/bash cat > /etc/profile.d/env.sh << EOF alias cdnet="cd /etc/sysconfig/network-scripts" alias editnet="vim /etc/sysconfig/network-scripts/ifcfg-ens33" # export PS1="[\[\e[31m\]\u\e[0m\]@\h \W]\\$ " export PATH=/app/bin:$PATH EOF cat > ~/.vimrc << EOF set nu EOF