Shell 是一個用 C 語言編寫的程序,它是用戶使用 Linux 的橋樑。Shell 腳本(shell script),是一種爲 shell 編寫的腳本程序。業界所說的 shell 通常都是指 shell 腳本,但要知道,shell 和 shell script 是兩個不同的概念。
1 變量的定義和使用
常用函數
形式 | 說明 | 備註 |
---|---|---|
# | 註釋 | |
echo | 用於向窗口輸出文本 | |
$0 | 顯示當前程序的名稱 | |
$* | 顯示所有輸入的參數 | |
$n | 顯示程序輸入第n個參數 | 如輸入n=1,表示輸入的第一個參數 |
$# | 顯示輸入參數的個數 | |
$? | 顯示命令執行的狀態 | 返回0代表成功,返回其他代表失敗 |
使用
在linux命令行下輸入以下命令。打印出/bin/bash
echo $Bash
通過建立demo.sh文件來建立shell腳本。shell中第一行一般都是#!/bin/bash表示引入環境,其他時候#表示註釋。shell中分爲環境變量和局部變量。常用變量定義如使用具體如下:
#!/bin/bash
# 打印hello world
echo "hello world!"
# 定義變量,=左右不能有空格:
A=10
# 通過$引用變量
echo $A
# 輸出當前路徑
echo $PWD
輸出結果爲:
hello world!
10
/home/hello/test/makes
在命令行下通過兩種方式來執行demo.sh文件
- 需要獲得linux文件權限
chmod 777 demo.sh
./demo.sh
- 不需要權限
/bin/bash demo.sh
常用變量
shell中還有許多常用變量,在demo.sh中添加以下內容
# 輸出當前文件名稱
echo $0
# 顯示從命令行傳入的第一個參數,空格分界
echo $1
# 顯示從命令行傳入的第二個參數
echo $2
# 輸出命令環境變量
# $輸出字符,需要轉義
# 顯示命令執行的狀態
echo "本文件輸入\$結果爲: $?"
# 顯示輸入參數的個數
echo "本文件輸入#結果爲: $#"
# 顯示所有輸入的參數
echo "本文件輸入*結果爲: $*"
命令行輸入./demo.sh param1 param2,輸出結果爲:
./demo.sh
param1
param2
本文件輸入$結果爲: 0
本文件輸入#結果爲: 2
本文件輸入*結果爲: param1 param2
當然也可以在命令行直接shell變量。如下命令命令行輸入, 返回表示變量0表示執行成功
echo 123 $?
輸出 123 0
但是在命令行中直接輸入以下命令echo $?,表示命令行輸入上一個命令是否成功。會返回非0值,表示執行失敗
echo $?
輸出 127
2 循環與文件讀寫
for循環
shell腳本中for循環的語法如下
for 變量 in 字符串
do
語句
done
命令行輸入下述命令可以遍歷1到15
seq 1 15
輸出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
通過for循環可以獲得同樣功能。在shell腳本中引入反引號可以調用系統命令,反引號``(位於按鍵1左邊)括起來的字符串被shell解釋爲命令行,在執行時,shell首先執行該命令行,並以它的標準輸出結果取代整個反引號(包括兩個反引號)部分。
建立demo.sh文件,鍵入以下內容:
#!/bin/bash
for i in `seq 1 15`
do
echo "當前數值 $i"
done
結果如下:
當前數值 1
當前數值 2
當前數值 3
當前數值 4
當前數值 5
當前數值 6
當前數值 7
當前數值 8
當前數值 9
當前數值 10
當前數值 11
當前數值 12
當前數值 13
當前數值 14
當前數值 15
對於shell腳本不能直接累加,需要使用expr命令。shell中expr命令是一個手工命令行計數器,命令行輸入:
expr 12+13
結果如下:
12+13
expr後面需要加空格才能正確輸出結果
expr 12 + 13
結果如下:
25
通過expr命令,可以進行累加計算,更改demo.sh內容如下:
#!/bin/bash
j=0
for((i=0;i<=100;i++))
do
j=`expr $i + $j`
done
echo "j的值爲:" $j
結果如下:
j的值爲: 5050
命令行輸入以下命令將當前所有文件打包爲tgz文件
tar czf all.tgz *
通過以下命令查找後綴爲.sh的文件
find . -name ‘*.sh’
但是不能壓縮指定文件。編寫shell腳本,可以將當前目錄和子目錄下所有.sh文件壓縮到result.tgz中
#!/bin/bash
for i in `find . -name "*.sh"`
do
tar -uf result.tgz $i
done
while循環
shell腳本中while循環的語法如下
while 條件語句
do
語句
done
循環打印0到10的demo.sh內容如下:
#!/bin/bash
i=0
while((i<10))
do
echo $i
i=`expr $i + 1`
done
結果如下:
0
1
2
3
4
5
6
7
8
9
另外也可通過for循環和read命令,讀取當前目錄text.txt中的內容
#!/bin/bash
while read line
do
echo $line
done<./text.txt
結果如下:
hello
world
!
4 if 語句
shell中if語句的語法有兩種,分別如下:
- 第一種
if(表達式);
fi
- 第二種
語句之前要有tab鍵,不能是空格,空格在shell語句中代表分割的特殊語義。
if(表達式);then
語句
else
語句
fi
例如判斷兩個變量大小的shell腳本實現如下:
#!/bin/bash
# 定義兩個變量
NUM1=100
NUM2=200
if(($NUM1>$NUM2));then
echo "NUM1 > NUM2"
else
echo "NUM1 < NUM2"
fi
輸出:
NUM1 < NUM2
shell中還有很多邏輯運算符,具體如下:
形式 | 說明 | 備註 |
---|---|---|
-f | 判斷文件是否存在 | |
-d | 判斷目錄是否存在 | |
-eg | 等於 | |
-ne | 不等於比較 | |
-le | 小於比較 | |
-ge | 大於或等於 | |
-a | 雙方都成立 | |
-o | 單方成立 |
例如判斷指定目錄是否存在,不存在就創建目錄的shell腳本爲:
#!/bin/bash
test=./test
# 判斷test目錄是否存在
if [ ! -d test ];then
# 創建文件夾
mkdir -p ./test
else
echo "目錄已經存在"
fi
其中需要用[]表示條件判斷。shell中各種括號用法見:
shell中各種括號(),[],(()),[[]],{}等的作用大全及示例
5 運算符
算法運算符
常用算數運算符如下,注意運算符的表達式要放在[]裏面,並且運算符前後要空格。
運算符 | 說明 | 舉例 | 備註 |
---|---|---|---|
+ | 加法 | expr 1 + 2 | 結果爲3 |
- | 減法 | expr 1 - 2 | 結果爲-1 |
* | 乘法 | expr 1 * 2 | 結果爲2 |
/ | 除法 | expr 1 / 2 | 結果爲0 |
% | 取餘 | expr 1 % 2 | 結果爲1 |
= | 賦值 | a=$b | 把變量b的值賦給a |
== | 相等 | &a == $b | 比較兩個數字是否相等,返回true或者false |
!= | 不相等 | &a != $b | 比較兩個數字是否不同,返回true或者false |
關係運算符
常用算數運算符如下
運算符 | 說明 |
---|---|
-eq | 檢測兩個數是否相等 |
-ne | 間隔兩個數是否不相等 |
-gt | 檢測左邊的數是否大於右邊 |
-lt | 檢測右邊的數是否大於左邊 |
-ge | 檢測左邊的數是否大於等於右邊 |
-le | 檢測左邊的數是否小於等於右邊 |
布爾運算符與邏輯運算符
運算符 | 說明 |
---|---|
! | 非運算 |
-o | 或運算 |
-a | 與運算 |
&& | 邏輯的AND |
|| | 邏輯的OR |
字符串運算符
運算符 | 說明 |
---|---|
= | 檢測兩個字符串是否相等 |
!= | 檢測兩個字符串是否不相等 |
-z | 檢測字符串長度是否爲0 |
-n | 檢測字符串長度是否不爲0 |
$ | 檢測字符串是否爲空 |
6 重定向
重定向表示改變輸入和輸出的方式,重定向分爲兩種,一種輸入重定向,一種是輸出重定向。輸出重定向的方式爲>,輸入重定向的方式爲<。0代表從標準輸入(默認鍵盤),1代表標準輸出(默認顯示屏),2代表錯誤輸出(默認顯示屏)。
比如下面命令表示將text.txt內容輸入到屏幕0
cat 0< text.txt
下面命令表示"hello world"輸出到file.txt文件
echo “hello world” > file.txt
7 函數
liunx shell中的函數和大部分編程語言中的函數一樣將代碼封裝到函數,供其他地方調用。
定義函數有兩種方式:
- 方式1
name()
{
command;
command2;
}
- 方式2
[ function ] funname [()]
{
action;
[return int;]
}
如定義一個test函數,打印hello world的shell腳本如下:
#!/bin/bash
function test()
{
output="hello world"
echo $output
}
# 調用test函數
test
但是在shell中函數沒有形參,我們可以通過$n獲得傳入的參數。如下:
#!/bin/bash
function test()
{
# 讀取傳入的參數
output=$1
echo $output
}
# 調用test函數
test "hello world"
計算階乘的函數的shell腳本如下:
#!/bin/bash
n=1;
factorial(){
for((i=1;i<=$1;i++))
do
n=$[$n * $i]
done
echo "$1的階乘是$n"
}
# $1從外界傳入參數
factorial $1
執行./demo.sh 3,結果爲
3的階乘是6
執行./demo.sh 10,結果爲
10的階乘是3628800
對於shell腳本的函數,只能返回狀態碼0到255。使用如下:
# 只能返回狀態碼0到255
fun()
{
# 從鍵盤讀取輸入的數值,將結果保存在num中
read -p "請輸入數值:" num
}
fun
# $?表示上一條指令執行的結果
echo "fun的返回值爲:$?"
結果如下:
請輸入數值:10
fun的返回值爲:0
但是可以用return自定義返回結果,如下:
#!/bin/bash
# 只能返回狀態碼0到255
fun()
{
# 從鍵盤讀取輸入的數值,將結果保存在num中
read -p "請輸入數值:" num
return $[ 2 * num ]
}
fun
# $?表示上一條指令執行的結果
echo "fun的返回值爲:$?"
結果如下:
請輸入數值:10
fun的返回值爲:20
但是自定義會返回值不能大於255,如執行函數
請輸入數值:200
fun的返回值爲:144