1. 程式人生 > >【shell指令碼】 變數基礎學習整理

【shell指令碼】 變數基礎學習整理

1.linux系統環境

echo 'echo /etc/profile ' >> /etc/profile
echo 'echo /etc/bashrc' >> /etc/bashrc
echo 'echo /root/.bashrc ' >> /root/.bashrc
echo 'echo /root/.bash_profile ' >> /root/.bash_profile

vi /etc/profile #在檔案的最後插入
export VAR9=xuegod #=等號兩邊不能有空格
source /etc/profile #重新載入profile檔案

 

$# 傳遞到指令碼的引數個數
$? 顯示最後命令的退出狀態;0表示沒有錯誤,其他任何值表明有錯誤
$! 後臺執行的最後一個程序的程序號pid

 

java環境安裝

rpm -ivh jdk-8u161-linux-x64.rpm
rpm -pql /root/jdk-8u161-linux-x64.rpm

vim /etc/profile
export JAVA_HOME=/usr/java/jdk1.8.0_161
export JAVA_BIN=/usr/java/jdk1.8.0_161/bin
export PATH=${JAVA_HOME}/bin:$PATH
export CLASSPATH
=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar source /etc/profile java -version

 

 獲取鍵盤引數

read a b
hello word

 

 

vim if-1.sh 
#!/bin/bash
if ls /mnt
then
echo "it's ok"
fi

 

 

20.2.2 雙分支if語句
語法格式:
if command ;
then
commands
else
commands
fi

多分支
if條件測試操作1 ; then
commands
elif 條件測試操作2 ; then
commands
elif 條件測試操作3 ; then
commands
.......
else
commands
fi

 

例4:判斷使用者在系統中是否存在,是否有家目錄

cat if-4.sh
#!/bin/bash
read -p "input a user:" tu
if grep $tu /etc/passwd ; then
echo "the user $tu exists on this system"
elif ls -d /home/$tu ; then
echo "the user $tu not exists on this system"
echo "$tu has a home directory"
else
echo "the user $tu not exists on this system"
echo "$tu not has a direcotry"
fi

 

test測試命令

整數比較

-eq 等
-ne 不等
-gt 大於
-ge 大於等於
-lt 小於
-le 小於等於

cat test2.sh 
#!/bin/bash
read -p "input var1 var2:" var1 var2
if [ $var1 -gt $var2 ] ; then
echo "$var1 > $var2"
elif [ $var1 -lt $var2 ] ; then
echo "$var1 < $var2"
else
echo "$var1 = $var2"
fi

 


注意:在做數值比較時,只能用整數

字串比較

== 等於
!= 不等於
-z 長度為零
-n 長度不為空
str1 > str2 大於
str1 < str2 小於

根據使用者名稱判斷是否是超級管理員

vi test3.sh
#!/bin/bash
read -p "input your name: " name
if [ $name == "root" ] ; then
echo "you are super administrator"
else
echo "You are a general user"
fi

 


例2:在做字串大小比較的時候,注意字串的順序
大於號和小於號必須轉義,要不然SHELL會把它當成重定向符號
大於和小於它們的順序和sort排序是不一樣的
在test比較測試中,它使用的是ASCII順序,大寫字母是小於小寫字母的;sort剛好相反

 cat test4.sh 
#!/bin/bash
var1=test
var2=Test
if [ $var1 \> $var2 ] ; then
echo "$var1 > $var2"
else
echo "$var1 < $var2"
fi 
[[email protected] ~]# bash test4.sh 
test > Test

 


-e 檔案或目錄存在
-r 檔案可讀
-w 檔案可寫
-x 檔案可執行
-s 有字元在
-d 目錄存在
-f 普通檔案存在
-c 是字元型檔案存在
-b 塊檔案存在
file1 -nt fle2 是否比後面新
file1 -ot file2 是否比後面舊

 

vim test5.sh 
#!/bin/bash
if [ -e /etc/passwd ] ; then
echo ok
else
echo err
fi 
[[email protected] ~]# bash test5.sh 
ok

test -e /etc/passwd && echo ok || echo err

 

 

例:清空日誌目錄

[[email protected] ~]# cat clear-log.sh 
#!/bin/bash
# clear /var/log/messages
#確定當前是root使用者
if [ $USER != "root" ];then
echo "你必須使用root使用者才能執行指令碼"
exit 10 #直接退出,並返回10
fi
#判斷檔案是否存在
if [ ! -f /var/log/messages ];then
echo "檔案不存在"
exit 12
fi
#保留最近100行的日誌內容
tail -100 /var/log/messages > /var/log/mesg.tmp
#日誌清理
>/var/log/messages
#cat /dev/null > /var/log/messages
mv /var/log/mesg.tmp /var/log/messages
echo "Logs clean up"

 

if [ 條件判斷一 ] && (||) [ 條件判斷二 ]; then
命令一
elif [ 條件判斷三 ] && (||) [ 條件判斷四 ]; then
命令二
else
執行其它
fi

 

vim umask.sh 
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
echo "umask 002"
else
echo "i am root :umask 022"
fi
[[email protected] ~]# bash umask.sh 
i am root :umask 022

 

例2:[[ 。。。 ]]和[ 。。。]的區別
[[… ]] 運算子是[… ]運算子的擴充;[[… ]]能夠支援 *,< 、>等符號且不需要轉義符

 

 if [ $USER == r* ] ;
 then echo "hello,$USER" ; 
else echo $USER not ; 
fi 
root not

 


#對比時r* ,就表示兩個字串 r*

也可以這樣寫:

 if [[ $USER == [a-z]oot ]] ; then echo "hello,$USER" ; else echo $USER not ;
fi

 


[[ 。。。 ]]和[ 。。。]的區別彙總:
1、所有的字元與邏輯運算子直接用“空格”分開,不能連到一起。
2、在[… ]表示式中,常見的> 、<需要加轉義符\,大小比較
3、進行邏輯運算子&& 、||比較時;如果用的[ ]符號,則用在外面,如[… ] && [… ] || [ …]如果在[…]裡面進行邏輯與或的比較,則用-a、-o進行表示,如[ x = y –a x < z –o x > m ]
4、[[… ]] 運算子只是[… ]運算子的擴充;能夠支援< 、>符號運算不需要轉義符;它還是以字串比較大小。裡面支援邏輯運算子 || 、 && , 不再使用-a 、-o
5、[[…]] 用 && 而不是 -a 表示邏輯“與”;用 || 而不是 -o表示邏輯“或”
6、[[… ]]可以進行算術擴充套件,而[ ... ]不可以
7、[[...]]能用正則,而[...]不行
8、雙括號(( ))用於數學表示式
9、雙方括號號[[ ]]用於高階字串處理,比如“模糊匹配”

 

20.5.1 實戰1:編寫指令碼檢查伺服器執行狀態

vim status.sh
#!/bin/bash
if [ $# -ge 1 ] ; then
systemctl status $1 > /dev/null
if [ $? -eq 0 ] ; then
echo "$1 服務正在執行"
else
systemctl start $1
fi
else
echo "執行指令碼的格式"
echo "sh $0 服務名"
fi

 

 

實戰2:根據學生的成績判斷

vi check_cj.sh 
#!/bin/bash
read -p "請輸入你的成績 " cj
if [ $cj -ge 0 ] && [ $cj -le 59 ] ;then
echo "補考"
elif [ $cj -ge 60 ] && [ $cj -le 70 ] ;then
echo "良好"
elif [ $cj -ge 71 ] && [ $cj -le 85 ] ;then
echo ""
elif [ $cj -ge 86 ] && [ $cj -le 100 ] ;then
echo "優秀" 
else
echo "成績的有效範圍是0-100之間"
fi

 

 


20.5.3 實戰3:每週一晚上3:00 ,備份資料庫伺服器上webdb庫的所有資料到系統的/mysqlbak目錄裡,使用系統日期做備份檔名。

vi mysqlbak.sh
#!/bin/bash
baknamefile=`date +%Y-%m-%d`
bakdir=/mysqlbak
user=root
password=123
dbname=webdb
[ -e $bakdir ] || mkdir $bakdir
mysqldump -u$user -p$password --flush-logs $dbname > $bakdir/${baknamefile}-webdb.sql

 

因為mysql咱們還沒有學,這裡以/etc目錄來做實驗:

 vi etcbak.sh
#!/bin/bash
baknamefile=`date +%Y-%m-%d`
bakdir=/etcbak
srcdir=/etc
[ -e $bakdir ] || mkdir $bakdir
tar zcvf ${bakdir}/${baknamefile}-etc.tar.gz /etc/
echo "========================"
ls -lh ${bakdir}/${baknamefile}-etc.tar.gz
echo "back etc is ok!"

 

 chmod +x etcbak.sh

 crontab -e
0 3 * * * /root/etcbak.sh 2>&1 > /dev/null