-- 1 --
Shell文件的擴展名并影響腳本的運行,一般用“.sh”是方便一眼認出是Shell文件。
學習某種語言寫的第一個程序當然是“Hello World捡偏!”了,如下:
#!/bin/bash
echo "Hello World !"
其中峡迷,“#!”是一種約定的標記银伟,它告訴系統這個腳本需要什么解釋器來執(zhí)行,即使用哪一種 Shell绘搞⊥埽“echo” 命令用于向窗口輸出文本。
運行Shell腳本有兩種方法夯辖, 首先cd 到相應目錄:
- chmod +x ./test.sh #使腳本具有執(zhí)行權限
./test.sh #執(zhí)行腳本 - /bin/sh test.sh
-- 2 -- Shell變量
- 定義變量時不需要美元符號($)琉预,也不需要聲明類型
- 變量名外面的花括號是可選的,加不加都行蒿褂,加花括號是為了幫助解釋器識別變量的邊界
- 使用一個定義過的變量圆米,只要在變量名前面加美元符號即可
#!/bin/bash
name_1="Hello"
name_2='Hello'
#echo為輸出命令
echo $name_1
echo "${name_1} World"
- 重新賦值
#!/bin/bash
name="Hello"
echo $name
#輸出Hello
name="Hello World"
echo $name
#輸出Hello World
- 只讀變量:使用 readonly 命令可以將變量定義為只讀變量,只讀變量的值不能被改變啄栓。
#!/bin/bash
name="Hello"
readonly name
name="Hello World"
#運行腳本娄帖,結果為:/bin/sh: NAME: This variable is read only.
- 刪除變量:使用 unset 命令可以刪除變量
#!/bin/bash
name="Hello"
unset name
echo $name
#運行后沒有任何輸出
- 字符串使用單引號和雙引號的區(qū)別:
- 單引號里的任何字符都會原樣輸出,單引號字符串中的變量是無效的昙楚;
單引號字串中不能出現單引號(對單引號使用轉義符后也不行)近速。 - 雙引號里可以有變量
雙引號里可以出現轉義字符
- 單引號里的任何字符都會原樣輸出,單引號字符串中的變量是無效的昙楚;
- 字符串相關操作:
str="abcdefghijkdmn"
echo ${#str}
#輸出字符串的長度:14
echo${str:1:4}
#提取字符串,輸出:bcde
# “#”號刪除堪旧,刪除左邊字符削葱,保留右邊字符天揖,從左邊開始刪除第一個匹配到的以及左邊所有字符娃肿。
echo ${str#*d}
#輸出:efghijkdmn
# “##”號刪除诡延,刪除左邊字符悉患,保留右邊字符进肯,從右邊開始刪除第一個匹配到的以及左邊所有字符诞挨。
echo ${str##*d}
#輸出:mn
# “%”號截取礁蔗,刪除右邊字符突硝,保留左邊字符,從右邊開始蛮瞄,刪除第一個 匹配到的及右邊的字符所坯。
echo ${str%d*}
#輸出:abcdefghidjk
# “%%”號截取,刪除右邊字符挂捅,保留左邊字符芹助,從左邊開始,刪除第一個 匹配到的及右邊的字符闲先。
echo ${str%%d*}
#輸出:abc
#從左邊第幾個字符開始状土,及字符的個數。
echo ${str:3:4}
#輸出:defg
#從左邊第幾個字符開始伺糠,一直到結束蒙谓。
echo ${str:3}
#輸出:defghidjkdmn
#從右邊第幾個字符開始,及字符的個數训桶。
echo ${str:0-7:4}
#輸出:idjk
#從右邊第幾個字符開始累驮,一直到結束。
echo ${str:0-7}
#輸出:idjkkdmn
-- 3 -- 數組
數組中可以存放多個值舵揭。Bash Shell 只支持一維數組(不支持多維數組)谤专,初始化時不需要定義數組大小(與 PHP 類似)午绳。
與大部分編程語言類似置侍,數組元素的下標由0開始。Shell 數組用括號來表示拦焚,元素用"空格"符號分割開蜡坊,如下:
#格式
array_name=(value1 ... valuen)
#!/bin/bash
m_array=(A b C)
echo ${m_array[*]}
#輸出:A b C
m_array[2]=D
echo ${m_array[*]}
#輸出:A b D
m_array[3]=E
echo ${m_array[*]}
#輸出:A b D E
echo ${m_array[@]}
#輸出:A b D E
echo ${#m_array[*]}
#輸出:4
echo ${#m_array[@]}
#輸出:4
-- 4 -- 基本運算符
表達式和運算符之間要有空格,例如 2+2 是不對的耕漱,必須寫成 2 + 2算色。
完整的表達式要被 包含抬伺,注意這個字符不是常用的單引號螟够,在 Esc 鍵下邊。
- 算術運算符
#!/bin/bash
val=`expr 2 + 2`
echo ${val}
#輸出:4
val_2=$val
echo ${val_2}
#輸出:4
sum=`expr $val \* $val_2`
echo ${sum}
#輸出:16
#乘號(*)前邊必須加反斜杠(\)才能實現乘法運算峡钓;
if [ $val == $val_2 ]
then
echo "相等"
fi
if [ $val != $val_2 ]
then
echo "不等"
fi
#輸出:相等
- 關系運算符
關系運算符只支持數字妓笙,不支持字符串,除非字符串的值是數字能岩。
#!/bin/bash
a=10
b=20
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b: a 不等于 b"
fi
#輸出:10 -eq 20: a 不等于 b
if [ $a -ne $b ]
then
echo "$a -ne $b: a 不等于 b"
else
echo "$a -ne $b : a 等于 b"
fi
#輸出:10 -eq 20: a 不等于 b
if [ $a -gt $b ]
then
echo "$a -gt $b: a 大于 b"
else
echo "$a -gt $b: a 不大于 b"
fi
#輸出:10 -eq 20: a 不大于 b
if [ $a -lt $b ]
then
echo "$a -lt $b: a 小于 b"
else
echo "$a -lt $b: a 不小于 b"
fi
#輸出:10 -eq 20: a 小于 b
if [ $a -ge $b ]
then
echo "$a -ge $b: a 大于或等于 b"
else
echo "$a -ge $b: a 小于 b"
fi
#輸出:10 -eq 20: a 小于 b
if [ $a -le $b ]
then
echo "$a -le $b: a 小于或等于 b"
else
echo "$a -le $b: a 大于 b"
fi
#輸出:10 -eq 20: a 小于或等于 b
- 布爾運算符
#!/bin/bash
a=10
b=20
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b: a 等于 b"
fi
#輸出:10 != 20 : a 不等于 b
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a -lt 100 -a $b -gt 15 : 返回 true"
else
echo "$a -lt 100 -a $b -gt 15 : 返回 false"
fi
#輸出:10 -lt 100 -a 20 -gt 15 : 返回 true
if [ $a -lt 100 -o $b -gt 100 ]
then
echo "$a -lt 100 -o $b -gt 100 : 返回 true"
else
echo "$a -lt 100 -o $b -gt 100 : 返回 false"
fi
#輸出:10 -lt 100 -o 20 -gt 100 : 返回 true
if [ $a -lt 5 -o $b -gt 100 ]
then
echo "$a -lt 100 -o $b -gt 100 : 返回 true"
else
echo "$a -lt 100 -o $b -gt 100 : 返回 false"
fi
#輸出:10 -lt 100 -o 20 -gt 100 : 返回 false
- 邏輯運算符
#!/bin/bash
a=10
b=20
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
#輸出:返回 false
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
#輸出:返回 true
- 字符串運算符
#!/bin/bash
a="abc"
b="efg"
if [ $a = $b ]
then
echo "a 等于 b"
else
echo "a 不等于 b"
fi
#輸出:a 不等于 b
if [ $a != $b ]
then
echo "a 不等于 b"
else
echo "a 等于 b"
fi
#輸出:a 不等于 b
if [ -z $a ]
then
echo "字符串長度為 0"
else
echo "字符串長度不為 0"
fi
#輸出:字符串長度不為 0
if [ -n $a ]
then
echo "字符串長度不為 0"
else
echo "字符串長度為 0"
fi
#輸出:字符串長度不為 0
if [ $a ]
then
echo "字符串不為空"
else
echo "字符串為空"
fi
#輸出:字符串為空
- 文件測試運算符
- 另:
EQ 就是 EQUAL等于
NQ 就是 NOT EQUAL不等于
GT 就是 GREATER THAN大于
LT 就是 LESS THAN小于
GE 就是 GREATER THAN OR EQUAL 大于等于
LE 就是 LESS THAN OR EQUAL 小于等于
-- 5 -- echo命令
仔細讀過上邊內容已經知道了echo的一些用法寞宫,那么還有一些其他的用法,如下:
#!/bin/bash
echo "It is a test"
#顯示普通字符串拉鹃,輸出:It is a test
echo "\"It is a test\""
#顯示轉義字符辈赋,輸出:"It is a test"
#外圍雙引號取消鲫忍,輸出也是一樣的:echo \"It is a test\"
echo "hello \n"
echo "abc"
#“\n”為換行
echo "hello \c"
#“\c”為不換行
echo "It is a test" > yourfile
#顯示結果定向至文件
name="a"
echo '$name\'
#原樣輸出字符串,不進行轉義或取變量(用單引號)钥屈,輸出:$name\
echo `date`
#顯示命令執(zhí)行結果悟民,輸出:Thu Aug 3 14:54:26 CST 2017(date為當前日期)
-- 6 -- printf 命令
#!/bin/bash
#先看這個例子
printf "%-10s %-8s %-4s\n" 姓名 性別 體重kg
printf "%-10s %-8s %-4.2f\n" 李小龍 男 66.1234
printf "%-10s %-8s %-4.2f\n" 齊天大圣孫悟空 男 48.6543
printf "%-10s %-8s %-4.2f\n" 姐姐 女 47.9876
其中:%s %c %d %f都是格式替代符
%-10s 指一個寬度為10個字符(-表示左對齊,沒有則表示右對齊)篷就,任何字符都會被顯示在10個字符寬的字符內射亏,如果不足則自動以空格填充,超過也會將內容全部顯示出來竭业。
%-4.2f 指格式化為小數智润,其中.2指保留2位小數。
#!/bin/bash
printf "%d %s\n" 1 "abc"
#輸出:1 abc
printf '%d %s\n' 1 "abc"
#輸出:1 abc(單引號與雙引號效果一樣 )
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
printf "我是一只:<%s>\n" "小鳥"
#輸出:我是一只:<小鳥>
-- 7 -- test 命令
- 數值測試
#!/bin/bash
num1=100
num2=100
if test $[num1] -eq $[num2]
then
echo '兩個數相等未辆!'
else
echo '兩個數不相等窟绷!'
fi
#輸出:兩個數相等!
- 字符串測試
num1="love"
num2="love"
if test $num1 = $num2
then
echo '兩個字符串相等!'
else
echo '兩個字符串不相等!'
fi
#輸出:兩個字符串相等!
- 文件測試
#!bin/bash
cd /bin
if test -e ./bash
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
-- 8 -- 流程控制
- if else / if else-if else
#!bin/bash
#格式如下鼎姐,之前已經寫了很多了
if condition
then
command1
command2
...
commandN
fi
#其中钾麸,sh的流程控制不可為空
a=10
b=20
if [ $a == $b ]
then
echo "a 等于 b"
elif [ $a -gt $b ]
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "沒有符合的條件"
fi
#輸出:a 小于 b
- for
#!/bin/bash
#格式如下:
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
for loop in 1 2 3 4
do
echo $loop
done
#換行輸出:
#1
#2
#3
#4
for str in 'I love you'
do
echo $str
done
#輸出:I love you
- while
#!/bin/bash
int=1
while(($int<=5))
do
echo $int
let "int++"
done
echo '按下 <CTRL-D> 退出'
echo -n '輸入你最喜歡的電影名: '
while read FILM
do
echo "是的!$FILM 是一部好電影"
done
- until 循環(huán)
until condition
do
command
done
- case
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
- bread
#!/bin/bash
while :
do
echo -n "輸入 1 到 5 之間的數字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你輸入的數字為 $aNum!"
;;
*) echo "你輸入的數字不是 1 到 5 之間的! 游戲結束"
break
;;
esac
done
- continue
#!/bin/bash
while :
do
echo -n "輸入 1 到 5 之間的數字: "
read aNum
case $aNum in
1|2|3|4|5) echo "你輸入的數字為 $aNum!"
;;
*) echo "你輸入的數字不是 1 到 5 之間的!"
continue
echo "游戲結束"
;;
esac
done
-- 9 -- 函數
函數格式:
[ function ] funname [()]
{
action;
[return int;]
}
1炕桨、可以帶function fun() 定義饭尝,也可以直接fun() 定義,不帶任何參數。
2献宫、參數返回钥平,可以顯示加:return 返回,如果不加姊途,將以最后一條命令運行結果涉瘾,作為返回值。 return后跟數值n(0-255)
#!/bin/bash
fun () {
echo "我是一個函數"
}
fun
#輸出:我是一個函數
fun () {
echo $(($1+$2)
}
fun 1 2
#輸出:3
注意捷兰,$10 不能獲取第十個參數立叛,獲取第十個參數需要${10}。當n>=10時贡茅,需要使用${n}來獲取參數秘蛇。
另外,還有幾個特殊字符用來處理參數:
-- 10 -- 輸入/輸出重定向
-- 11 -- 文件包含
格式如下:
. filename # 注意點號(.)和文件名中間有一空格
#或
source filename
one.sh代碼:
#!/bin/bash
one_name="ok"
two.sh代碼:
#!/bin/bash
#使用 . 號來引用test1.sh 文件
. ./one.sh
# 或者使用以下包含文件代碼
# source ./test1.sh
echo $one_name
#運行two.sh后顶考,輸出:one_name = ok