一、什么是腳本文件 ?
腳本就是命令解析器,包含一系列命令序列的文本文件。當(dāng)運(yùn)行這個(gè)腳本文本時(shí),文件中包含的命令序列將得到執(zhí)行。 如果我們有一系列經(jīng)常使用的 Linux 命令,我們可以把它們存儲在一個(gè)文件中。腳本會讀取這個(gè)文件并執(zhí)行其中的命令。這樣的文件被稱為腳本文件。
例如:
run.sh
#!/bin/bashlspwdcd ..touch hello.c12345
二、編寫Shell腳本
1. 基本規(guī)則
(1)腳本文件命名的后綴必須是.sh
。(2)Shell腳本內(nèi)容的第一行必須是#!/bin/bash
,告訴操作系統(tǒng)使用哪個(gè)解釋器來執(zhí)行腳本文件中的命令。它指示系統(tǒng)使用位于 /bin/bash 路徑下的 Bash shell 來執(zhí)行腳本。(3)腳本文件里以#作為語句的注釋。(4)使用echo
輸出內(nèi)容。(5)使用cat
查看文件內(nèi)容。
2. shell 變量
shell 變量沒有數(shù)據(jù)類型,都是字符串,即使數(shù)值也是字符串。
變量使用
(1)創(chuàng)建變量
命令:變量名稱=值
。等號兩邊不能有空格!如果值有空格則必須用""或者’’引用起來。
#!/bin/basha=10b=" 10"readonly c=3 #只讀變量,不可修改1234
(2)引用變量
命令:$變量名
。以下三種引用變量的方式等價(jià)。
#!/bin/basha=10echo $aecho ${a} echo "${a}"12345
運(yùn)行腳本:輸出三行 10
(3)刪除變量
命令:unset 變量名
。
#!/bin/basha=10unset a echo $a1234
因?yàn)橹虚g刪除了變量,所以不會輸出任何東西。
(4)從鍵盤讀取變量
命令:read 變量
。允許用戶從鍵盤輸入,實(shí)現(xiàn)程序交互。
#!/bin/bashecho "please input the first number:"read aecho "This number is: $a"1234
變量類型
(1)特殊變量
a.sh
#!/bin/bashecho $1echo $2echo $3echo $0echo $#echo $@echo $*echo $?echo $$echo "finally"1234567891011
(2)系統(tǒng)/環(huán)境變量
系統(tǒng)預(yù)定義的變量,一般在/etc/profile 中進(jìn)行定義。使用env
查看所有系統(tǒng)變量。HOME
:用戶主目錄 PATH 文件搜索路徑。PWD
:用戶當(dāng)前工作目錄。PS1、PS2
:提示符。LOGNAME
:指登錄主機(jī)的用戶名稱;HOSTNAME
:主機(jī)名字,也就是這個(gè)系統(tǒng)的名字。USER
:指目前環(huán)境使用者的名稱。等等…還有其他的系統(tǒng)變量。
使用:export 變量名
,把 變量變?yōu)槿肿兞俊W優(yōu)槿肿兞亢?,就可以在多個(gè)文件里使用該變量。
但是在命令行,使用export聲明為全局變量后,只對當(dāng)前的命令窗口有效。如果要想始終有效可以直接將環(huán)境變量添加到bashrc中去。使用vi ~/.bashrc
編輯,添加進(jìn)入后,使用source ~/.bashrc
刷新來使得文件生效。
3. 重定向符
使用重定向符時(shí),文件不存在則自動(dòng)創(chuàng)建文件。
#!/bin/bashecho hello > 1.c #將 hello 輸入到 1.c文件里cat < 1.c > 2.c #從1.c文件里獲取內(nèi)容,輸出到2.c文件里cat 2.c #查看2文件里的內(nèi)容1234
4. 管道 ‘ | ’
管道操作符|
用于連接左右兩個(gè)命令,將|
左邊的命令執(zhí)行結(jié)果(輸出)作為|
右邊命令的輸入。
5. 單雙引號
' '
和" "
的區(qū)別:單引號:消除所有字符的特殊意義。雙引號:消除除了$、" " 、’ ’ 三種以外其它字符的特殊意義。
#!/bin/basha=10echo ${a} #輸出:10echo "${a}" #輸出:10echo '${a}' #輸出:${a}12345
5. grep搜索匹配
命令:grep [選項(xiàng)] 搜索字符 在哪個(gè)文件搜索(文件名)
選項(xiàng)作用- i忽略大小寫,不區(qū)分大小寫地匹配模式。- r遞歸地搜索目錄及其子目錄下的文件。- l只打印包含匹配模式的文件名,而不打印匹配的行。- n打印匹配行的行號。- v反轉(zhuǎn)匹配,只打印不匹配模式的行。- w僅匹配整個(gè)單詞,而不是部分匹配。- c打印匹配模式的行數(shù)統(tǒng)計(jì)。
舉例:1.txt 內(nèi)容如下
"hello world""this is a test"12
使用命令:grep "hello" 1.txt
6. 運(yùn)算符
#!/bin/bashVAR=2 test $VAR -gt 1 echo $?VAR1=3 [ $VAR1 -gt 1 ] #中括號兩邊必須要有空格echo $? 12345678910
6. 數(shù)組
(1)數(shù)組的定義方式1:a=(1 2 3 4 5) ,各個(gè)數(shù)據(jù)之間用空格隔開。方式2:a[0]=1; a[1]=2; a[2]=3方式3:a=([1]=1 [2]=2)
(2)數(shù)組的引用
舉例:
#!/bin/basha=(2 5 7 10)echo ${a[2]} #輸出下標(biāo)為 2 的數(shù)據(jù)echo ${#a[*]} #輸出數(shù)組的長度echo ${a[@]:2} #截取下標(biāo)從 2 到最后echo ${a[@]:1:2} #截取從下標(biāo) 1 后面 2 個(gè)1234567
7. if 語句
注意:在使用if語句時(shí),將if
和then
放在不同行,如同行放置,則 if 語句必須要;
結(jié)束。
#!/bin/bash#方式一if [ $USER == "slef" ]then echo $USERfi#方式二if [ $PWD == "/home/slef/" ];then echo $PWDfi#方式三if [ $PWD == "/home/slef/" ];then echo "HOME $PWD"elif [ $PWD == "/mnt/hgfs/share/5.shell/3" ]then echo "SHARE $PWD"else echo "else"fi1234567891011121314151617181920212223
8. case語句
#!/bin/bashcase $1 in "y") echo inputed y ;; "n") echo inputed n ;; *) echo "inputed *" ;;esac12345678910111213
9. for循環(huán)
#!/bin/bash#方式一for i in 1 2 3 4 5do echo $idone#方式二for ((i=0;i<5;i++))do echo $idone#方式三for i in /etc/*do echo $idone1234567891011121314151617181920
10. while語句
#!/bin/bashvar=0while [ $var -ne 10 ]do echo $var var=$(($var+1))done123456789
11. until 語句
#!/bin/bashmyvar=0until [ $myvar -eq 10 ]do echo $myvar myvar=$(($myvar+1))done12345678
12. Shell 函數(shù)
#!/bin/bashfunc(){ echo "hello world" echo $0 echo $1 return 255}func 12 33exit 0echo $?1234567891011121314
三、編寫except腳本-自動(dòng)交互
告訴系統(tǒng)使用expect解釋器來執(zhí)行這個(gè)腳本。模擬用戶輸入來與命令交互, 根據(jù)命令的輸出提示, 來執(zhí)行相應(yīng)的操作, 來實(shí)現(xiàn)自動(dòng)化。安裝except解釋器:sudo apt-get install expect
。
test.exp
#!/usr/bin/expect# 設(shè)置變量set user "HwHiAiUser" set host "192.168.21.8"set password "Mind@123"#使用 spawn 啟動(dòng) scp 命令,將文件 test 傳輸?shù)竭h(yuǎn)程主機(jī)的用戶主目錄。spawn scp test $user@$host:~# 處理密碼提示expect { "password:" { send "$password\r" } "yes/no" { send "yes\r" expect "password:" { send "$password\r" } }}# 等待 scp 進(jìn)程結(jié)束expect eof