shell腳本:
包含一些命令或聲明,並符合必定格式的文本文件
格式要求:首行shebang機制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perlpython
建立shell腳本
第一步:使用文本編輯器來建立文本文件
第一行必須包括shell聲明序列:#!
示例:#!/bin/bash
添加註釋
註釋以#開頭
第二步:運行腳本
給予執行權限,在命令行上指定腳本的絕對或相對路徑
直接運行解釋器,將腳本做爲解釋器程序的參數運行正則表達式
腳本調試
檢測腳本中的語法錯誤
bash -n /path/to/some_script
調試執行
bash -x /path/to/some_script
變量
變量:命名的內存空間
變量:變量類型shell
Shell中命名建議規則:
一、變量名大寫
二、局部變量小寫
三、函數名小寫
四、用英文名字,並體現出實際做用
bash中變量的種類
根據變量的生效範圍等標準劃分下面變量類型
局部變量:生效範圍爲當前shell進程;對當前shell以外的其它shell進程,
包括當前shell的子shell進程均無效
環境變量:生效範圍爲當前shell進程及其子進程
本地變量:生效範圍爲當前shell進程中某代碼片段,一般指函數
位置變量:$1, $2, ...來表示,用於讓腳本在腳本代碼中調用經過命令行傳
遞給它的參數
特殊變量:$?, $0, $*, $@, $#,$$
局部變量bash
變量賦值:name=‘value’
可使用引用value
(1) 能夠是直接字串:name=「root"
(2) 變量引用:name="$USER"
(3) 命令引用:name=COMMAND
name=$(COMMAND)dom
變量引用:${name} 或者 $name
" " 弱引用,其中的變量引用會被替換爲變量值
' ' 強引用,其中的變量引用不會被替換爲變量值,而保持原字符串編輯器
顯示已定義的全部變量:set
刪除變量:unset nameide
環境變量
變量聲明、賦值:
export name=VALUE
declare -x name=VALUE
變量引用:
$name, ${name}
顯示全部環境變量:
env
printenv
export
declare -x
刪除變量:
unset name
環境變量
bash內建的環境變量
PATH SHELL USER
UID HOME PWD
SHLVL LANG MAIL
HOSTNAME HISTSIZE
_ 下劃線 上個命令最後的字符串函數
只讀和位置變量
只讀變量:只能聲明,但不能修改和刪除
聲明只讀變量:
readonly name
declare -r name
查看只讀變量:
readonly -p測試
位置變量:在腳本代碼中調用經過命令行傳遞給腳本的參數
$1, $2, ... 對應第一、第2等參數,shift [n]換位置
$0 命令自己
$ 傳遞給腳本的全部參數,所有參數合爲一個字符串
$@ 傳遞給腳本的全部參數,每一個參數爲獨立字符串
$# 傳遞給腳本的參數的個數
注意:$@ $ 只在被雙引號包起來的時候纔會有差別
set -- 清空全部位置變量ui
退出狀態
進程使用退出狀態來報告成功或失敗
0 表明成功,1-255表明失敗
$? 變量保存最近的命令退出狀態
例如:
ping -c1 -W1 hostdown &> /dev/null
echo $?
退出狀態碼
bash自定義退出狀態碼
exit [n]:自定義退出狀態碼
注意:腳本中一旦遇到exit命令,腳本會當即終止;終止退出狀態取決於exit命
令後面的數字
注意:若是未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決於腳本中執行
的最後一條命令的狀態碼
算術運算
bash中的算術運算:help let
+, -, *, /, %取模(取餘), **(乘方),乘法符號有些場景中須要轉義
實現算術運算:
(1) let var=算術表達式
(2) var=$[算術表達式]
(3) var=$((算術表達式))
(4) var=$(expr arg1 arg2 arg3 ...)
(5) declare –i var = 數值
(6) echo ‘算術表達式’ | bc
bash有內建的隨機數生成器變量:$RANDOM(0-32767)
示例:生成 0 - 49 之間隨機數
echo $[$RANDOM%50]
賦值
加強型賦值:
+=, -=, *=, /=, %=
例如:let count+=3
自加3後自賦值
自增,自減:
let var+=1 let var++
let var-=1 let var--
邏輯運算
true, false
1, 0
與 或 非
短路運算
短路與&
第一個爲0,結果一定爲0
第一個爲1,第二個必需要參與運算
短路或|
第一個爲1,結果一定爲1
第一個爲0,第二個必需要參與運算
異或:^
異或的兩個值,相同爲假,不一樣爲真
條件測試
判斷某需求是否知足,須要由測試機制來實現
測試命令:
• test EXPRESSION
• [ EXPRESSION ]
• [[ EXPRESSION ]]
注意:EXPRESSION先後必須有空白字符
條件性的執行操做符
根據退出狀態而定,命令能夠有條件地運行
• && 表明條件性的AND THEN
• || 表明條件性的OR ELSE
例如:
grep -q no_such_user /etc/passwd || echo 'No such user'
No such user
ping -c1 -W2 station1 &> /dev/null \
&& echo "station1 is up" \
|| (echo 'station1 is unreachable'; exit 1)
station1 is up
test命令
長格式的例子:
test "$A" = "$B" && echo "Strings are equal"
test 「$A」 -eq 「$B」 && echo "Integers are equal"
簡寫格式的例子:
[ "$A" = "$B" ] && echo "Strings are equal"
[ "$A" -eq "$B" ] && echo "Integers are equal"
bash的數值測試
-v VAR
變量VAR是否設置
數值測試:
-gt 是否大於
-ge 是否大於等於
-eq 是否等於
-ne 是否不等於
-lt 是否小於
-le 是否小於等於
bash的字符串測試
字符串測試:
= 是否等於
ascii碼是否大於ascii碼
< 是否小於
!= 是否不等於
=~ 左側字符串是否可以被右側的PATTERN所匹配
注意: 此表達式通常用於[[ ]]中;擴展的正則表達式
-z "STRING「 字符串是否爲空,空爲真,不空爲假
-n "STRING「 字符串是否不空,不空爲真,空爲假
注意:用於字符串比較時的用到的操做數都應該使用引號
Bash的文件測試
存在性測試
-a FILE:同-e=
-e FILE: 文件存在性測試,存在爲真,不然爲假
存在性及類別測試
-b FILE:是否存在且爲塊設備文件
-c FILE:是否存在且爲字符設備文件
-d FILE:是否存在且爲目錄文件
-f FILE:是否存在且爲普通文件
-h FILE 或 -L FILE:存在且爲符號連接文件
-p FILE:是否存在且爲命名管道文件
-S FILE:是否存在且爲套接字文件
Bash的文件權限測試
文件權限測試:
-r FILE:是否存在且可讀
-w FILE: 是否存在且可寫
-x FILE: 是否存在且可執行
文件特殊權限測試:
-u FILE:是否存在且擁有suid權限
-g FILE:是否存在且擁有sgid權限
-k FILE:是否存在且擁有sticky權限
Bash的文件屬性測試
文件大小測試:
-s FILE: 是否存在且非空
文件是否打開:
-t fd: fd 文件描述符是否在某終端已經打開
-N FILE:文件自從上一次被讀取以後是否被修改過
-O FILE:當前有效用戶是否爲文件屬主
-G FILE:當前有效用戶是否爲文件屬組
Bash的文件屬性測試
雙目測試:
FILE1 -ef FILE2: FILE1是不是FILE2的硬連接
FILE1 -nt FILE2: FILE1是否新於FILE2(mtime)
FILE1 -ot FILE2: FILE1是否舊於FILE2
Bash的組合測試條件
第一種方式:
COMMAND1 && COMMAND2 而且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[ -f 「$FILE」 ] && [[ 「$FILE」=~ .*.sh$ ]]
第二種方式:
EXPRESSION1 -a EXPRESSION2 而且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必須使用測試命令進行,[[ ]] 不支持
示例:
[ -z 「$HOSTNAME」 -o $HOSTNAME "=="localhost.localdomain" ] \
&& hostname www.magedu.com
[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab
使用read來把輸入值分配給一個或多個shell變量
-p 指定要顯示的提示
-s 靜默輸入,通常用於密碼
-n N 指定輸入的字符長度N
-d ‘字符’ 輸入結束符
-t N TIMEOUT爲N秒
read 從標準輸入中讀取值,給每一個單詞分配一個變量
全部剩餘單詞都被分配給最後一個變量
read -p 「Enter a filename: 「 FILE
條件選擇if語句
選擇執行:
注意:if語句可嵌套
單分支
if 判斷條件;then
條件爲真的分支代碼
fi
雙分支
if 判斷條件; then
條件爲真的分支代碼
else
條件爲假的分支代碼
fi
if 語句
多分支
if 判斷條件1; then
條件1爲真的分支代碼
elif 判斷條件2; then
條件2爲真的分支代碼
elif 判斷條件3; then
條件3爲真的分支代碼
else
以上條件都爲假的分支代碼
fi
逐條件進行判
斷,第一次遇爲「真」條件時,執行其分支,然後結束整個if語句
If示例
根據命令的退出狀態來執行命令
if ping -c1 -W2 station1 &> /dev/null; then
echo 'Station1 is UP'
elif grep "station1" ~/maintenance.txt &> /dev/null; then
echo 'Station1 is undergoing maintenance‘
else
echo 'Station1 is unexpectedly DOWN!'
exit 1
fi
條件判斷:case語句
case 變量引用 inPAT1)
PAT2)
分支2
;;
...
)
默認分支
;;
esac
case支持glob風格的通配符:
: 任意長度任意字符
?: 任意單個字符
[]:指定範圍內的任意單個字符
a|b: a或b
bash如何展開命令行
把命令行分紅單個命令詞
展開別名
展開大括號的聲明({})
展開波浪符聲明(~)
命令替換$() 和 `)<br/>再次把命令行分紅命令詞<br/>展開文件通配(*、 ?、 [abc]等等)<br/>準備I/0重導向(<、 >)<br/>運行命令<br/>防止擴展<br/>反斜線(\)會使隨後的字符按原意解釋<br/>$ echo Your cost: \$5.00<br/>Your cost: $5.00<br/>加引號來防止擴展<br/>• 單引號(’ )防止全部擴展<br/>• 雙引號(」 )也防止全部擴展,可是如下狀況例外:<br/>$(美圓符號) - 變量擴展<br/>
(反引號) - 命令替換
\(反斜線) - 禁止單個字符擴展
!(歎號) - 歷史命令替換
bash的配置文件
按生效範圍劃分,存在兩類:
全局配置:
/etc/profile
/etc/profile.d/.sh
/etc/bashrc
我的配置:
~/.bash_profile
~/.bashrc
shell登陸兩種方式
交互式登陸:
(1)直接經過終端輸入帳號密碼登陸
(2)使用「su - UserName」 切換的用戶
執行順序:/etc/profile --> /etc/profile.d/.sh --> ~/.bash_profile -->~/.bashrc --> /etc/bashrc
非交互式登陸:
(1)su UserName
(2)圖形界面下打開的終端
(3)執行腳本
(4)任何其它的bash實例
執行順序: /etc/profile.d/.sh --> /etc/bashrc -->~/.bashrcProfile類按功能劃分,存在兩類:profile類和bashrc類profile類:爲交互式登陸的shell提供配置全局:/etc/profile, /etc/profile.d/.sh我的:~/.bash_profile功用:(1) 用於定義環境變量(2) 運行命令或腳本Bashrc類bashrc類:爲非交互式和交互式登陸的shell提供配置全局:/etc/bashrc我的:~/.bashrc功用:(1) 定義命令別名和函數(2) 定義本地變量編輯配置文件生效修改profile和bashrc文件後需生效兩種方法:1從新啓動shell進程2 . 或source例:. ~/.bashrcBash 退出任務保存在~/.bash_logout文件中(用戶)在退出登陸shell時運行用於• 建立自動備份• 清除臨時文件$-變量h:hashall,打開這個選項後,Shell 會將命令所在的路徑hash下來,避免每次都要查詢。經過set +h將h選項關閉i:interactive-comments,包含這個選項說明當前的 shell 是一個交互式的shell。所謂的交互式shell,在腳本中,i選項是關閉的。m:monitor,打開監控模式,就能夠經過Job control來控制進程的中止、繼續,後臺或者前臺執行等。B:braceexpand,大括號擴展H:history,H選項打開,能夠展開歷史列表中的命令,能夠經過!感嘆號來完成,例如「!!」 返回上最近的一個歷史命令,「!n」 返回第 n 個歷史命令