概述
Shell的概念是源自Unix的命令解釋器。Shell不只可解釋用戶輸入的命令,同時,可解釋執行基於命令的腳本語言。使用shell腳本能提升用戶操做和管理員進行系統管理的效率。shell腳本擅長處理純文本類型的數據,而Linux中幾乎全部的配置文件、日誌都是純文本類型。python
編寫腳本
腳本書寫規範
- 腳本統一存放目錄
- 選擇解釋器, 開頭要寫#! XXX,內核根據#!後的解釋器來肯定用哪一個解釋器解釋腳本內容
- 編輯腳本使用vim, 配置~/.vimrc方便我的書寫習慣
- 文件名規範,結尾以sh結束
shell的基本元素
- #!/bin/bash 必須的,指出shell的類型
- #註釋。在shell中,註釋寫在#以後,#以後的內容不會執行
- 變量
- 控制 循環分支
shell中的特殊符號
- #! 註明執行腳本採用的shell
a表示變量a的值。變量 字符長度超過1個時,用{}括起來
- 單引號。 被引發的字符所有作普通字符,即所有原樣echo 'my $SHELL'
- 雙引號 引號內的內容,除$、轉義符\、倒引號`這三個保留特殊功能,其餘字符均作普通字符。
- 倒引號(數字1鍵旁邊的那個鍵) 引號內的字符串當作shell命令行解釋執行(一樣的功能也可使用$()來使用),獲得的結果 取代整個倒引號括起來的部分。
- 反斜線 反斜線是轉義字符,它能把特殊字符變成普通字符。在某個字符前面利用反斜槓(\)可以阻止 shell把後面的字符解釋爲特殊字符。
- 表明0個或者多個特殊字符 例子 yum. 表明的可使yum.也能夠是yum.a、yum.ab、yum.abc 固然小數點後面能夠有多個字母
- ? 表明的是任意一個字符 例子 yum.? 能夠是yum.a yum.b yum.c,可是要注意小數點後面必須有任意一個字符
- [] 表明的是中括號中的任意一個
- [abcdef] 能夠是a b c d e f 中的任意一個字母固然也能夠是數字
- [-]表明的是一個範圍
- [a-z] 表示的是字母a到z之間的全部字母[^]^是反向選擇符號從字面意思能夠知道也就是非的意思
- [^abc]表示只要不a b c 這三個字符中的任意一個就選擇
- $( ) 能夠將命令替換輸出賦值給變量
- {} 經過括號擴展能夠生成須要的字串,括號中能夠包含連續的序列或使用逗號分隔的多個項目,連續的序列包括一個起點和一個終點
user@computer: ~$ echo {a,b,c}
a b c
user@computer: ~$ echo user{1,5,8}
user1 user5 user8
user@computer: ~$ echo {0..10}
0 1 2 3 4 5 6 7 8 9 10
user@computer: ~$ mkdir {dir1,dir2,dir3}
user@computer: ~$ ls –ld dir{1,2,3}
複製代碼
變量
shell變量能夠保存路徑名、文件名或者一個數字等。分爲三類:shell
- 本地變量: (局部變量)只在建立它們的Shell中使用,能夠在shell程序內任意使用和修改它 們。
- 環境變量: 能夠在建立它們的Shell及其派生出來的任意子程序中使用。有些變量是用戶建立 的,其餘的則是專用的(好比PATH、HOME)。是系統環境的一部分,沒必要去定義它們,能夠在 shell程序中使用它們 。還能在shell中加以修改。
- 內部變量: 由系統提供的。與環境變量不一樣,用戶不能修改它們。
本地變量
本地變量 在用戶如今的shell生命期的腳本中使用編程
使用本地變量的注意事項
- 等號兩邊不能夠有空格
- 取值包含空格,必須用雙引號括起來
- Shell變量能夠用大小寫字母,區分大小寫
- 變量是弱類型的, 不用聲明類型
變量聲明及賦值格式
變量=值(等號兩邊不能有空格)
複製代碼
變量的引用
$變量名
${變量名}
變量名爲1個字符時建議使用方式一,多餘一個字符時建議使用方式二
舉例: $a ${abc}
複製代碼
清除變量
unset 變量名
user@computer: ~$ name=Jack
user@computer: ~$ echo ${name}
user@computer: ~$ unset name
複製代碼
設置只讀變量
設置變量時,不想再改變其值,能夠將之設爲只讀變量
變量名=值
readonly 變量名
複製代碼
環境變量
Bash預設了不少環境變量,實際使用中,能夠直接調用這些變量。環境變量能夠用於全部子程序,着包括編輯器、腳本和應用vim
內置環境變量
變量 |
意義 |
HOME |
表明使用者的家目錄。cd ~ 去到使用者的家目錄 或者利用 cd 就能夠直接回到使用者家目錄了。 |
SHELL |
目前這個環境使用的 SHELL 是哪一個程序? 若是是 bash 的話,預設是 /bin/bash |
PWD |
用戶當前工做目錄的路徑。它指出用戶目前在Linux文件系統中處在什麼位置。它是由Linux自動設置的 |
HISTSIZE |
這個與「歷史命令」有關,曾經下達過的指令能夠被系統記錄下來,而記錄的「數目」則是由這個值來設定的。 |
PATH |
就是執行文件搜尋的路徑,目錄與目錄中間以冒號(:)分隔,因爲文件的搜尋是依序由PATH的變量內的目錄來查詢,因此,目錄的順序也很重要。 |
環境變量注意事項
- 環境變量能夠在命令行中設置,但用戶註銷時這些值將丟失
- 環境變量均爲大寫
- 必須用export命令導出
設置環境變量
variable-name=value
export variable-name(環境變量名大寫)
複製代碼
顯示環境變量
env 能夠看到全部的環境變量
echo $環境變量名 (顯示一個變量)
複製代碼
清除環境變量
unset 環境變量名
複製代碼
修改path環境變量
修改PATH環境變量,使腳本不用加路徑,直接輸入文件名字便可執行。
如下在用戶user主目錄下操做:
mkdir shdir && cd shdir
vi hello
chmod 755 hello
cd ~
export PATH=$PATH:$HOME/shdir
在任何目錄下,輸入hello便可執行該文件。
本方式下環境變量若是修改錯了,exit退出後從新登錄便可恢復系統默認的值。
複製代碼
配置文件中修改環境變量
注意,修改環境變量前最好先備份一下舊的:
export tem=$PATH
echo $tem >>pathbake
須要知道環境變量與哪些配置文件有關:不一樣發行版會有不一樣,但命名仍是有通性的:
find / -name 「*profile」
find / -name 「*bashrc」
全局配置文件/etc/profile
本地配置文件~/.bashrc
複製代碼
內部變量
內部變量是Linux所提供的一種特殊類型的變量,這類變量在程序中用來做出判斷。在shell程序內這類變量的值是不能修改的。數組
部份內部變量
變量 |
意義 |
$# |
傳送給shell程序的位置參數的數量 |
$? |
最後命令的完成碼或者在shell程序內部執行的shell程序(返回值) |
$0 |
shell程序的名稱 |
$* |
調用shell程序時所傳送的所有參數的單字符串,"參數1", "參數2"…形式保存的參數 |
$@ |
"參數1", "參數2"…形式保存的參數 |
$n |
第n個參數 |
$$ |
本程序的PID |
$! |
上一個命令的PID |
輸入與輸出
輸入
read [選項] 變量名列表
經常使用選項
-a ANAME 將輸入讀入ANAME的數組
-n NCHARS 讀入N個字符
-p PROMPT 顯示一個提示
-r 取消轉移
-s 安靜模式,輸入的字符將不會提示
-t TIMEOUT 超過指定時間,read自動中止
複製代碼
輸出
echo [選項] 字符串
經常使用選項
-n 不在最後自動換行
-e 啓用反斜線控制字符的轉換
-E 不處理轉義字符。此爲缺省選項;
複製代碼
#! /bin/bash
read -p 'please type some words, I will print them: ' words
echo $words
複製代碼
條件測試
test 條件表達式
若是測試條件爲真,test命令會返回0,不然返回一個非0的數值
test 語句與if/then和case語句一塊兒,構成shell編程的控制轉移結構
複製代碼
[] 條件表達式
[ 條件表達式 ]
方括號的內側兩邊各需一個空格
條件表達式的值爲真返回零,爲假時返回非零值
複製代碼
文件狀態判斷
條件語句 |
真假 |
-d filename |
若文件filename爲目錄文件,則返回真 |
-f filename |
文件是否存在且爲普通文件,則返回真 |
-r filename |
若文件filename可讀,則返回真 |
-s filename |
若文件filename的長度大於0,則返回真 |
-w filename |
若文件filename可寫,則返回真 |
-x filename |
若文件filename可執行,則返回真 |
-e filename |
文件是否存在 |
#! /bin/bash
read -p 'input file path: ' file
if [ -e $file ]
then
echo '文件存在'
else
echo '文件不存在'
fi
複製代碼
條件語句
if
if [ 條件表達式 ]; then
命令序列
fi
當"條件表達式"的測試值爲真時,執行"命令序列",不然,執行條件語句後面的命令。條件表達
式與then之間的分號";"起命令分隔符的做用。
複製代碼
if-else
if [ 條件表達式 ]
then
命令序列1
else
命令序列2
fi
當"條件表達式"的測試值爲真時,執行"命令序列1",不然,執行"命令序列2"。命令序列中的命令
能夠是一個或者多個。
複製代碼
if-elif-else
if test 條件表達式1
then
命令序列1
elif [ 條件表達式2 ]
then
命令序列2
else
命令序列3
fi
這是包含二層嵌套的條件語句,當"條件表達式1"爲真時,執行"命令序列1",不然,在"條件表 達式2"爲真的狀況下,執行"命令序列2",不然,執行"命令序列3","命令序列3"屬於第2個條
件語句的一部分。
複製代碼
應用舉例
#! /bin/bash
read -p 'please input the file path: ' file
if [ -d $file ]
then
echo 'this is a directory'
elif [ -f $file ]
then
echo 'this is a file'
else
echo 'wrong file type, or the file do not exist'
fi
複製代碼
數字操做符
操做符 |
含義 |
n1 –eq n2 |
判斷數字n1與n2是否相等,若相等,返回0,不然,返回1 |
n1 –ne n2 |
判斷數字n1與n2是否不等,若不等,返回0,不然,返回1 |
n1 –lt n2 |
判斷數字n1是否小於n2,如果,返回0,不然,返回1 |
n1 –gt n2 |
判斷數字n1是否大於n2,如果,返回0,不然,返回1 |
n1 –le n2 |
判斷數字n1是否小於或等於n2,如果,返回0,不然,返回1 |
n1 –ge n2 |
判斷數字n1是否大於或等於n2,如果,返回0,不然,返回1 |
字符串操做符
操做符 |
含義 |
string |
若字符串string非空,則返回真 |
-n string |
若字符串string長度大於0,則返回真 |
-z string |
若字符串string長度爲0,則爲返回真 |
string1 = string2 |
若字符串string1和string2相等,則返回真 |
string1 != string2 |
若字符串string1和 string2不等,則返回真 |
邏輯操做符
操做符 |
含義 |
e1 –a e2 |
邏輯表達式e1和e2同時爲真時,返回0,不然,返回1 |
e1 –o e2 |
邏輯表達式e1和e2有一個爲真時,返回0,不然,返回1 |
! e1 |
若邏輯表達式e1不爲真時,返回0,,不然,返回1 |
循環語句
python風格for循環
for 變量名 in 參數列表
do
命令列表
done
將"參數列表"中的元素依次賦給"變量名",在每次賦值後執行"命令列表","參數列表"表示"變 量名"的取值範圍
複製代碼
c語言風格for循環
for ((初始化變量值;結束循環條件;運算))
do
命令序列
done
複製代碼
while
while [ 條件表達式 ]
do
命令列表
done
循環執行"命令列表"中的命令,直至"條件表達式"的值爲假。
複製代碼
until
Until [ 條件 ]
do
命令序列
Done
直到條件知足時循環結束
複製代碼
應用舉例
#! /bin/bash
directory=$1
if [ ! $directory ]
then
echo "please input the argument directory"
exit
fi
files=`ls ${directory}`
for file in $files;
do
if [ -f ${file} ]
echo $file
then
suffix=${file#*\.}
echo $suffix
if [[ $suffix == "txt" ]]
then
prefix=${file%\.*}
mv $directory/$file $directory/$prefix.doc
fi
fi
done
複製代碼
函數
functionname() {
命令列表
return
}
函數的調用方式爲:
functionname arguments
複製代碼