Shell Script

0. 命令
  • 顯示命令的詳細(xì)說明
man ls
輸入q退出說明
  • 標(biāo)準(zhǔn)輸出
echo Hello
顯示不換行
echo "OK!\c"
echo "It is a test"
~~~~~~~~~~~~~
輸出:OK!It is a test
  • 原樣輸出
aaa="  tt"
echo $aaa
echo "$aaa"
~~~~~~~~~~~~~
輸出:
tt
    tt
  • 優(yōu)先執(zhí)行
echo $(ls)
echo `ls`
  • 帶顏色輸出
echo "\033[字背景顏色;文字顏色m字符串\033[0m"
echo "\033[31;36msomething here\033[0m"
  • 輸出重定向覆蓋文件
ls > ~/Desktop/out.m
  • 輸出重定向追加文件
ls >> ~/Desktop/out.m
  • 輸入
read a
echo $a
這種輸入會忽略前面的空格
  • 原樣輸入
IFSbak=$IFS
IFS="\n"
read -r a
echo $a
IFS=$IFSbak
這種輸入不會忽略前面的空格
  • 命令替換
命令替換是指Shell可以先執(zhí)行命令,將輸出結(jié)果暫時保存,在適當(dāng)?shù)牡胤捷敵?x=`ls ./`
echo "當(dāng)前目錄下有\(zhòng)n$x"
  • printf,echo命令的增強(qiáng)版
printf "Hello, Shell\n"
printf 不像 echo 那樣會自動換行,必須顯式添加換行符(\n)
# format-string為雙引號
printf "%d %s\n" 1 "abc"
# 單引號與雙引號效果一樣 
printf '%d %s\n' 1 "abc"
# 沒有引號也可以輸出
printf %s abcdef
# 格式只指定了一個參數(shù),但多出的參數(shù)仍然會按照該格式輸出,format-string 被重用
$ printf %s abc def
abcdef
$ printf "%s\n" abc def
abc
def
$ printf "%s %s %s\n" a b c d e f g h i j
a b c
d e f
g h i
j
# 如果沒有 arguments,那么 %s 用NULL代替,%d 用 0 代替
$ printf "%s and %d \n" 
and 0
  • 獲得當(dāng)前正在執(zhí)行的腳本的存放路徑
basepath=$(cd `dirname $0`; pwd)
~~~~~~~~~~~~~
dirname $0,取得當(dāng)前執(zhí)行的腳本文件的父目錄
cd `dirname $0`,進(jìn)入這個目錄(切換當(dāng)前工作目錄)
pwd,顯示當(dāng)前工作目錄(cd執(zhí)行后的)
  • 字符串轉(zhuǎn)換為指令: eval
從文件按行讀取,并echo的例子
d=tt
while read myline
do
a="echo $myline"
eval $a
done < test.txt
~~~~~~~~~~~~~
test.txt里面是
a
b
c
$d
則輸出
a
b
c
tt
1. 指定腳本解釋器
腳本第一行
#!/bin/sh
或者
#!/bin/bash
2. 注釋

以“#”開頭的行就是注釋,會被解釋器忽略。
多行,可以把這一段要注釋的代碼用一對花括號括起來,定義成一個函數(shù),沒有地方調(diào)用這個函數(shù),這塊代碼就不會執(zhí)行,達(dá)到了和注釋一樣的效果。

3. 變量
  • 定義變量,不加$ (在for和forin循環(huán)頭部也不加),變量名和等號之間不能有空格,變量可以重新定義,變量不能含有保留字,不能含有 "-" 等保留字符,也不能含有空格。
aaa="name"
aaa=20
for aaa in `ls ~`
  • 使用變量,
$aaa
${aaa}
  • 局部變量
a=aaa
function test {
local a=bbb
echo $a
}
echo $a
test
echo $a
  • 只讀變量
x="xxxx"
readonly x
  • 刪除變量
x="xxxx"
unset x
不能刪除只讀變量
  • 特殊變量
變量 含義
$0 當(dāng)前腳本的文件名
$n 傳遞給腳本或函數(shù)的參數(shù)。n 是一個數(shù)字,表示第幾個參數(shù)。例如,第一個參數(shù)是$1,第二個參數(shù)是$2(當(dāng)n>=10時,需要使用${n}來獲取參數(shù))
$# 傳遞給腳本或函數(shù)的參數(shù)個數(shù)
$* 傳遞給腳本或函數(shù)的所有參數(shù)
$@ 傳遞給腳本或函數(shù)的所有參數(shù)。被雙引號(" ")包含時,與 $* 稍有不同。不被雙引號(" ")包含時,都以"$1" "$2" … "$n" 的形式輸出所有參數(shù)。但是當(dāng)它們被雙引號(" ")包含時,"$*" 會將所有的參數(shù)作為一個整體,以"$1 $2 … $n"的形式輸出所有參數(shù);"$@" 會將各個參數(shù)分開,以"$1" "$2" … "$n" 的形式輸出所有參數(shù)。
$? 上個命令的退出狀態(tài)(成功會返回 0,失敗返回 1),或函數(shù)的返回值
$$ 當(dāng)前Shell進(jìn)程ID。對于 Shell 腳本,就是這些腳本所在的進(jìn)程ID
  • 腳本傳參
test.sh
echo "First Parameter : $1"
echo "First Parameter : $2"
~~~~~~~~~~~~~
sh test.sh a b
輸出:
First Parameter : a
First Parameter : b
  • 函數(shù)傳參
func() {
    let "sum = $1 + $2"
    return $sum
}
~~~~~~~~~~~~~
func 1 2
echo "sum=$?"
4. 字符串
  • 單引號里的任何字符都會原樣輸出,單引號字符串中的變量是無效的
    單引號字串中不能出現(xiàn)單引號(對單引號使用轉(zhuǎn)義符后也不行)
str='this is a string'
  • 雙引號里可以有變量
    雙引號里可以出現(xiàn)轉(zhuǎn)義字符
str="Hello, I know your are \"$your_name\"! \n"
  • 不用引號,不能有空格
str=thisisastring
  • 拼接字符串
echo $aaa$bbb"sufix"
  • 獲取字符串長度
echo ${#string}
  • 提取子字符串
string="abcdefg"
echo ${string:1:3}
輸出:bcd
  • 字符串包含
str="this is a string"
[[ $str =~ "this" ]] && echo "str contains this"
[[ $str =~ "that" ]] || echo "str does NOT contain that"
~~~~~~~~~~~~~
也可以把[[ $str =~ "this" ]]作為條件使用if語句
  • 字符串替換
aaa=tat
echo ${aaa//a/b}
~~~~~~~~~~~~~
輸出:
tbt
5. 數(shù)組
  • 定義
array_name=(
value0
value1
value2
value3
)
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
  • 讀取
value=${array_name[2]}
使用@ 或 * 可以獲取數(shù)組中的所有元素
${array_name[*]}
${array_name[@]}
  • 獲取數(shù)組的長度
# 取得數(shù)組元素的個數(shù)
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得數(shù)組單個元素的長度
lengthn=${#array_name[n]}
  • 把數(shù)組作為參數(shù),并在函數(shù)中遍歷
func() {
lines=$1
for line in ${lines[*]}
do
echo $line
done
}
aaa=(
value0
value1
value2
)
func "${aaa[*]}"
6. 條件
  • sh的流程控制不可為空
    if [ $aa -eq 0 ],方括號是一個可執(zhí)行程序,必須加空格,不能寫成if [$aa -eq 0]
  • if
a=0
if [ $a -eq 0 ]
then
echo hello
fi
a=0
if [ $a -eq 0 ]; then echo hello; fi
  • if else
a=0
if [ $a -eq 0 ]
then
echo hello
else
echo hell
fi
a=59
if [ $a -gt 90 ]
then
echo good
elif [ $a -gt 60 ]
then
echo normal
else
echo zhazha
fi
7. for
  • for in
for file in `ls ~`
do
echo $file
done
~~~~~~~~~~~~~
輸出:
Desktop
Documents
Downloads
Library
...
for file in ls ~
do
echo $file
done
~~~~~~~~~~~~~
輸出:
ls
/Users/barbere
for file in "ls ~"
do
echo $file
done
~~~~~~~~~~~~~
輸出:
ls ~
  • C風(fēng)格的for
for (( i=0; i<3; i++ ))
do
echo $i
done
8. while
i=10
while [ $i -gt 5 ]
do
echo $i
i=`expr $i - 1`
done
無限循環(huán)
while :
do
command
done
9. case
read opt
case "${opt}" in
"a" )
echo choose $opt
exit;;
"b" )
echo choose $opt
exit;;
"c" )
echo choose $opt
exit;;
"Exit" )
exit;;* ) echo "Bad option, please choose again"
esac
10. break & continue
break n
表示跳出第 n 層循環(huán)
continue n
結(jié)束當(dāng)前循環(huán),繼續(xù)下一個(n是層)
11. 文件包含
  • 讀入test2.sh的內(nèi)容并執(zhí)行其內(nèi)容
. ~/Desktop/test2.sh
12. 運(yùn)算
  • 四則運(yùn)算
let "x = $x + 2"
x=`expr $x + 2`
let "x = $x - 2"
x=`expr $x - 2`
let "x = $x * 2"
x=`expr $x \* 2`
let "x = $x / 2"
x=`expr $x / 2`
let "x = $x % 2"
x=`expr $x % 2`
無浮點(diǎn)數(shù)
  • 關(guān)系運(yùn)算符,只支持?jǐn)?shù)字,不支持字符串,除非字符串的值是數(shù)字
運(yùn)算符 含義
-eq 檢測兩個數(shù)是否相等,相等返回 true
-ne 檢測兩個數(shù)是否相等,不相等返回 true
-gt 檢測左邊的數(shù)是否大于右邊的,如果是,則返回 true
-lt 檢測左邊的數(shù)是否小于右邊的,如果是,則返回 true
-ge 檢測左邊的數(shù)是否大等于右邊的,如果是,則返回 true
-le 檢測左邊的數(shù)是否小于等于右邊的,如果是,則返回 true
  • 布爾運(yùn)算符
運(yùn)算符 含義 舉例
! 非運(yùn)算 [ ! false ] 返回 true
-o 或運(yùn)算 [ $a -lt 20 -o $b -gt 100 ]
-a 與運(yùn)算 [ $a -lt 20 -a $b -gt 100 ]
  • 字符串運(yùn)算符
運(yùn)算符 含義 舉例
= 檢測兩個字符串是否相等 [ $a = $b ]
!= 檢測兩個字符串是否不相等 [ $a != $b ]
-z 檢測字符串長度是否為0 [ -z $a ]
-n 檢測字符串長度是否不為0 [ -z $a ]
str 檢測字符串是否為空 [ $a ]
13. 函數(shù)
square() {
let "res = $1 * $1"
return $res
}
read y
square $y
result=$?
echo $result
~~~~~~~~~~~~~
函數(shù)返回值,可以顯式增加return語句;如果不加,會將最后一條命令運(yùn)行結(jié)果作為返回值。
Shell 函數(shù)返回值只能是整數(shù),一般用來表示函數(shù)執(zhí)行成功與否,0表示成功,其他值表示失敗。如果 return 其他數(shù)據(jù),比如一個字符串,往往會得到錯誤提示:“numeric argument required”。
如果一定要讓函數(shù)返回字符串,那么可以先定義一個變量,用來接收函數(shù)的計(jì)算結(jié)果,腳本在需要的時候訪問這個變量來獲得函數(shù)返回值。
func_res=default
func() {
func_res=$1
}
read y
func $y
echo result is $func_res
14. 簡單選擇界面
OPTIONS="A B"
select opt in $OPTIONS; do
if [ "$opt" = "A" ]; then
echo select A
exit
elif [ "$opt" = "B" ]; then
echo select B
exit
else
echo bad option
fi
done
15. 參考資料

qinjx/30min_guides
Linux Bash Shell快速入門
Shell教程
shell腳本中echo顯示內(nèi)容帶顏色的實(shí)現(xiàn)方法
shell讀取文件每一行的方式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容