1、腳本調試-腳本運行前要進行腳本調試
bash -n /path/to/some_script 檢測腳本中的語法錯誤
bash -x /path/to/some_script 調試執行
2、shell是弱類型編程語言
1)、無須指定變量類型,默認為字符型;變量參與運算會自動進行隱式類型轉換;變量無須事先定義可直接調用
如:bash 不支持浮點數
2)變量命名法則
不能使程序中的保留字:例如if, for
只能使用數字、字母及下劃線,且不能以數字開頭
見名知義
統一命名規則,例如駝峰命名法
3、本地變量
生效范圍為當前shell進程,對當前shell 之外的其它shell 進程,包括當前shell 的子shell 進程均無效;
1)、變量賦值:name=‘value’
可以使用引用value:
(1) 可以是直接字串; name=“root"
(2) 變量引用:name="$USER"
(3) 命令引用:name=` COMMAND `, name =$(COMMAND)
"" :弱引用,其中的變量引用會被替換為變量值
'' :強引用,其中的變量引用不會被替換為變量值,而保持原字符串
2)、變量引用即是引用或者使用變量的值,格式為:${name}, $name;前一種格式較為穩妥
3)、顯示已定義的所有變量:set
刪除變量:unset name
4、環境變量:生效范圍為當前shell及其子子孫孫shell進程
變量聲明、賦值:
export name=VALUE
declare -x name=VALUE
變量引用:$name, ${name}
顯示所有環境變量:
export
env
printenv
刪除:unset name
bash 有許多內建的環境變量:PATH, SHELL, USRE,UID,HISTSIZE,HOME,PWD,OLDPWD,HISTFILE,PS1
5、只讀變量:只能聲名,但不能修改和刪除
readonly name=value
declare -r name=value
6、位置變量:在腳本代碼中調用通過命令行傳遞給腳本的參數
$1, $2, … :對應第1 、第2 等參數(但是地址變量$10指的是第一個參數$1和0的組合,例如$1參數是x,那么$10就是x0)
$0: 命令本身,例如/root/bin/arg.sh
$*: 傳遞給腳本的所有參數,全部參數合為一個字符串
$@: 傳遞給腳本的所有參數,每個參數為獨立字符串
$#: 傳遞給腳本的參數的個數
$@ $* 只在被雙引號包起來的時候才會有差異
例如f1.sh腳本#!/bin/bash
f2.sh “$*”
f2.sh “$@”
7、算術運算
bash 中的算術運算:
+, -, *, /, % (取余), ** (乘方)
實現算術運算:
(1) let var= 算術表達式
(2) var=$[ 算術表達式]
(3) var=$(( 算術表達式))
(4) echo ‘算術表達式’ | bc
乘法符號有些場景中需要轉義,如*
bash 有內建的隨機數生成器:$RANDOM (1-32767)
echo $[$RANDOM%50] 生成0-49 之間隨機數
8、賦值
增強型賦值:+=, -=, *=, /=, %=
let varOPERvalue
例如:let count+=3,意思是變量count自加3 后自賦值
let var++
let var—
后置加加和前置加加
i++ 表示i的值作為表達式的值,然后i自加1
++i 表示i先自加1再作為表達式的值
9、邏輯運算
true, false
1, 0
與:
1 與 1 = 1
1 與 0 = 0
0 與 1 = 0
0 與 0 = 0
或:
1 或 1 = 1
1 或 0 = 1
0 或 1 = 1
0 或 0 = 0
命令true,#true命令執行后#echo $?的返回值是0
命令false,#false命令執行后#echo $?的返回值是非零任意數
短路與&&:exp1 如果為假,exp2就不運算;也是exp1為真,exp2就運算
短路或||:exp1 如果為真,exp2就不運算;也是exp1為假,exp2就運算
異或^:exp1與exp2相同為假,不同為真
10、聚集命令
有兩種聚集命令的方法:
? 復合式:date; who | wc –l 命令會一個接一個地運行
? 子shell式 :(date; who | wc -l ) >> /tmp/trace 所有的輸出都被發送給單個STDOUT 和STDERR
11、退出狀態
進程可以使用退出狀態來報告成功或失敗
$? 變量保存最近的命令退出狀態,可以在腳本中使用,保存的是前一個緊挨著的命令的執行狀態
#echo $? 返回值為0代表成功,1-255 代表失敗
例如:
#ping -c1 -W1 hostIP &> /dev/null
# echo $?
(第一條命令中:-c1選項表示ping一次,-W1表示1秒)
12、退出狀態碼
exit [n]:自定義退出狀態碼
例如,在腳本中最后一行寫入exit 99,則腳本運行結束后,無論腳本倒數第二行的命令成功或者失敗,則查看退出狀態時#echo $?的返回值都是99
注意:腳本中一旦遇到exit 命令,腳本會立即終止,終止退出狀態取決于exit 命令后面的數字,若exit命令后無數字,則終止退出狀態碼取決于此exit命令前一條命令的執行結果成敗取0或者非零的任意數
注意:如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決于腳本中執行的最后一條命令的狀態碼
13、條件測試
測試命令:
? test EXPRESSION
? [ EXPRESSION ]
? [[ EXPRESSION ]],雙中括號有更強適用性
注意:若使用第二、三條測試命令,則EXPRESSION 前后必須有空白字符
&&與||是條件性的執行操作符
示例(雙引號):
$ 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"
14、bash 的測試類型
1)、數值測試:
-gt: 是否大于;
-ge: 是否大于等于;
-eq: 是否等于;
-ne: 是否不等于;
-lt: 是否小于;
-le: 是否小于等于;
2)、字符串測試:
== :是否等于;
>: ascii碼是否大于ascii碼
<: 是否小于
!=: 是否不等于
=~: 左側字符串是否能夠被右側的PATTERN所匹配
(注意: 此上表達式一般用于[[ ]]中)
-z "STRING" :字符串是否為空,空為真,不空為假
-n "STRING" :字符串是否為空,不空為真,空為假
(注意:用于字符串比較時的用到的操作數都應該使用引號)
3)、文件測試
存在性測試
-a FILE :同-e
-e FILE : 文件存在性測試,存在為真,否則為假;
存在性及類別測試
-b FILE :是否存在且為塊設備文件
-c FILE :是否存在且為字符設備文件
-d FILE :是否存在且為目錄文件
-f FILE :是否存在且為普通文件
-h FILE 或 -L FILE :是否存在且為符號鏈接文件
-p FILE :是否存在且為命名管道文件
-S FILE :是否存在且為套接字文件
文件權限測試:-r、-w、-x
文件特殊權限測試:
-g FILE :是否存在且擁有sgid 權限
-u FILE :是否存在且擁有suid 權限
-k FILE :是否存在且擁有sticky權限
文件大小測試:
-s FILE: 是否存在且非空,也即非空為真,#[ -s FILE ]執行后#echo $?的返回值是0
文件是否打開:
-N FILE :文件自上一次被讀取之后是否被修改過,也即是atime在mtime前就是自上一次讀取后被修改過,#[ -N FILE ]執行后#echo $?的返回值是0
-O FILE :當前有效用戶是否為文件屬主
-G FILE :當前有效用戶是否為文件屬組
雙目測試:
FILE1 -ef FILE2: FILE1與FILE2是否指向同一個設備上的相同inode,也即是FILE1與FILE2是否是硬鏈接的關系,如是為真,不是為假
FILE1 -nt/-ot FILE2: FILE1是否新/舊于FILE2,比較的是FILE1與FILE2的修改時間,也即mtime
15、組合測試條件
第一種方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[ -e FILE ] && [ -r FILE ]
第二種方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION 非
如:# [ -z “$HOSTNAME” -o "$HOSTNAME" =="localhost.localdomain" ] && hostname www.magedu.com
主機名為空或者是localhost.localdomain,那么就定義主機名為www.magedu.com
# [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab
如果/bin/cat是存在且為普通文件并且/bin/cat有執行權限,那么就執行cat /etc/fstab
16、使用read 命令來接受輸入
read 從標準輸入即鍵盤輸入中讀取值,分配給一個或多個shell變量
-p 指定要顯示的提示信息
用法:read -p “Enter a filename:” FILE
示例:指定文件做為參數,編寫腳本判斷文件是否為.sh后綴,如果是,添加x權限;不是,則提示xxf
#!/bin/bash
read -p "please input the file:" a
A1=`echo $a | grep -o "\.[^.]\+$"`
[[ "$A1" == ".sh" ]] && chmod +x $a || echo xxf
17、腳本example.sh未賦予權限時,使用bash、source及 .
1)、使用bash運行相當于開了一個子shell example.sh,example.sh里面的變量當前終端shell不可引用;
2)、使用source和 .運行example.sh腳本,就相當于直接在當前終端運行腳本example.sh內變量和命令代碼,所有example.sh里面的變量可以為當前終端shell引用
所以可知,bash是給腳本用的,source和 .是給配置文件使用的
例如example.sh腳本位于當前root用戶的家目錄下,為#!/bin/bash
a=haha
PATH=/XXX
echo PATH=$PATH
cd /tmp
那么如果使用source或者 .來運行腳本example.sh,比如# . /root/example.sh后
輸出的結果是PATH=/XXX,同時當前的目錄變為/tmp,實際上變量a和PATH是定義于當前終端上了,故而
再#echo $a 的輸出結果是haha,而不是為空
#echo $PATH 的輸出結果是/XXX,而不再是默認的PATH路徑,因為原先的PATH變量被替換
#pwd 的返回值是/tmp,而不是當前root用戶的家目錄/root
原創文章,作者:18612763863,如若轉載,請注明出處:http://www.www58058.com/35548