0. 命令
man ls
輸入q退出說明
echo Hello
顯示不換行
echo "OK!\c"
echo "It is a test"
~~~~~~~~~~~~~
輸出:OK!It is a test
aaa=" tt"
echo $aaa
echo "$aaa"
~~~~~~~~~~~~~
輸出:
tt
tt
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 "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í)行后的)
從文件按行讀取,并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
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ù)
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
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 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 ~
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)算
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)算 |
[ ! false ] 返回 true |
| -o |
或運(yùn)算 |
[ $a -lt 20 -o $b -gt 100 ] |
| -a |
與運(yùn)算 |
[ $a -lt 20 -a $b -gt 100 ] |
| 運(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讀取文件每一行的方式