shell編程基礎

shell腳本:
包含一些命令或聲明,並符合一定格式的文本文件
格式要求:首行shebang機制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl

創建shell腳本
第一步:使用文本編輯器來創建文本文件
第一行必須包括shell聲明序列:#!
示例:#!/bin/bash
添加註釋
註釋以#開頭
第二步:運行腳本
給予執行權限,在命令行上指定腳本的絕對或相對路徑
直接運行解釋器,將腳本作爲解釋器程序的參數運行

腳本調試
檢測腳本中的語法錯誤
bash -n /path/to/some_script
調試執行
bash -x /path/to/some_script
變量
變量:命名的內存空間
變量:變量類型

Shell中命名建議規則:
1、變量名大寫
2、局部變量小寫
3、函數名小寫
4、用英文名字,並體現出實際作用
bash中變量的種類
根據變量的生效範圍等標準劃分下面變量類型
局部變量:生效範圍爲當前shell進程;對當前shell之外的其它shell進程,
包括當前shell的子shell進程均無效
環境變量:生效範圍爲當前shell進程及其子進程
本地變量:生效範圍爲當前shell進程中某代碼片斷,通常指函數
位置變量:$1, $2, ...來表示,用於讓腳本在腳本代碼中調用通過命令行傳
遞給它的參數
特殊變量:$?, $0, $*, $@, $#,$$
局部變量

變量賦值:name=‘value’
可以使用引用value
(1) 可以是直接字串:name=“root"
(2) 變量引用:name="$USER"
(3) 命令引用:name=COMMAND
name=$(COMMAND)

變量引用:${name} 或者 $name
" " 弱引用,其中的變量引用會被替換爲變量值
' ' 強引用,其中的變量引用不會被替換爲變量值,而保持原字符串

顯示已定義的所有變量:set
刪除變量:unset name

環境變量
變量聲明、賦值:
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, ... 對應第1、第2等參數,shift [n]換位置
$0 命令本身
$ 傳遞給腳本的所有參數,全部參數合爲一個字符串
$@ 傳遞給腳本的所有參數,每個參數爲獨立字符串
$# 傳遞給腳本的參數的個數
注意:$@ $
只在被雙引號包起來的時候纔會有差異
set -- 清空所有位置變量

退出狀態
進程使用退出狀態來報告成功或失敗
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重導向(&lt;、 &gt;)<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 -->~/.bashrc
Profile類
按功能劃分,存在兩類:
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
例:
. ~/.bashrc
Bash 退出任務
保存在~/.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 個歷史命令

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章