shell腳本的本質
shell腳本語言是解釋型語言
shell腳本的本質:shell命令的有序集合
shell編程的基本過程
-
建立shell文件——包含任意多行操作系統命令或shell命令的文本文件;
-
賦予shell文件執行權限——用chmod命令修改權限;
-
執行shell文件——直接在命令行上調用shell程序;
shell變量
shell允許用戶建立變量存儲數據,但不支持數據類型(整形、字符、浮點型),將任何賦給變量的值都解釋爲一串字符
Bourne Shell有如下四種變量:
-
用戶自定義變量
-
位置變量即命令行參數
-
預定義變量
-
環境變量
用戶自定義變量
在shell編程中通常使用全大寫變量,方便識別
$COUNT=1
變量調用:在變量前加$
$echo $HOME
使用unset命令刪除變量的賦值
$unset COUNT
shell程序和語句
shell程序由零或多條shell語句構成。shell語句包括三大類:說明性語句、功能性語句和結構性語句
說明性語句:以#號開始到該行結束,不被解釋執行
功能性語句:任意shell命令、用戶程序或其它shell程序
結構性語句:條件測試語句、多路分支語句、循環語句、循環控制語句等
expr命令
算術運算命令expr主要用於進行簡單的整數運算,包括加+、減-、乘\*
、除/、求模%等操作。
test語句
test語句可測試三種對象:字符串 整數 文件屬性
每種測試對象都有若干測試操作符
字符串測試
s1 = s2 | 測試兩個字符串的內容是否完全一樣 |
---|---|
s1 != s2 | 測試兩個字符串的內容是否有差異 |
-z s1 | 測試s1字符串的長度是否爲0 |
-n s1 | 測試s1字符串的長度是否不爲0 |
整數測試
a -eq b | 測試a與b是否相等 |
---|---|
a -ne b | 測試a與b是否不相等 |
a -gt b | 測試a是否大於b |
a -ge b | 測試a是否大於等於b |
a -lt b | 測試a是否小於b |
a -le b | 測試a是否小於等於b |
文件測試
-d name | 測試name是否爲一個目錄 |
---|---|
-e name | 測試一個文件是否存在 |
-f name | 測試name是否爲普通文件 |
-L name | 測試name是否爲符號鏈接 |
-r name | 測試name文件是否存在且爲可讀 |
-w name | 測試name文件是否存在且爲可寫 |
-x name | 測試name文件是否存在且爲可執行 |
-s name | 測試name文件是否存在且其長度不爲0 |
f1 -nt f2 | 測試文件f1是否比文件f2更新 |
f1 -ot f2 | 測試文件f1是否比文件f2更舊 |
結果:
結構性語句
結構性語句主要根據程序的運行狀態、輸入數據、變量的取值、控制信號以及運行時間等因素來控制程序的運行流程。
主要包括:條件測試語句、多路分支語句、循環語句、循環控制語句和後臺執行語句等。
條件語句
if [ 表達式]
then 命令表
fi
如果表達式爲真,則執行命令表中的命令;否則執行fi後面的語句。if和fi是條件語句的括號語句,必須成對使用;命令表中的命令可以是一條,也可以是多條。
if 表達式
then 命令表1
else 命令表2
fi
如果表達式爲真,則執行命令表1中的命令,再退出if語句;否則執行命令表2中的語句,再退出if語句。
多路分支語句
case 字符串變量 in
模式1)
命令表1
;;
模式2 | 模式3)
命令表2
;;
.......
模式n)
命令表n
;;
esac
編寫一個shell腳本來判斷成績的等級
#!/bin/bash
echo -n "Please input score:"
read S
if [ $S -lt 0 -o $S -gt 100 ]
then
echo "not in [0-100]"
exit
fi
G=`expr $S / 10`
case $G in
9|10)
echo "$S A"
;;
6|7|8)
echo "$S B"
;;
*)
echo "$S C"
esac
結果:
循環語句for
當循環次數已知或確定時,使用for循環語句來多次執行一條或一組命令。循環體由語句括號do和done來限定。
for 變量名 in 單詞表
do
命令表
done
變量依次取單詞表中的各個單詞,每取一次單詞,就執行一次循環體中的命令,循環次數由單詞表中的單詞數確定。命令表中的命令可以是一條,也可以是由分號或換行符分開的多條。
#!/bin/bash
sum=0
for i in `seq 1 100`
do
sum=`expr $sum + $i`
done
echo $sum
for ((i=1;i<=10;i++))
do
echo $i
done
結果:
循環語句
while 命令或表達式
do
命令表
done
while語句首先測試其後的命令或表達式的值,如果爲真,就執行一次循環體中的命令,然後再測試該命令或表達式的值,執行循環體,直到該命令或表達式爲假時退出循環。
while語句的退出狀態爲命令表中被執行的最後一條命令的退出狀態。
shell函數調用
value_name=`function_name [arg1 arg2 ... ]`
function_name [arg1 arg2 .. ]
echo $?
函數變量作用域
全局作用域:在腳本的其他任何地方都能夠訪問該變量
局部作用域:只能在聲明變量的作用域內訪問。
聲明局部變量的格式:
Local variable_name =value
GNU工具
編譯工具:把一個源程序編譯爲一個可執行程序
調試工具:能對執行程序進行源碼或彙編級調試
軟件工程工具:用於協助多人開發或大型軟件項目的管理
其他工具:用於把多個目標文件鏈接成可執行文件的鏈接器,或者用作格式轉換的工具
GCC簡介
全稱爲GNU CC,GNU項目中符合ANSI C標準的編譯系統
編譯如C、C++、Object C、Java、Fortran、Pascal、Modula-3和Ada等多種語言
GCC是可以在多種硬體平臺上編譯出可執行程序的超級編譯器,其執行效率與一般的編譯器相比平均效率要高20%~30%
一個交叉平臺編譯器,適合在嵌入式領域的開發編譯
編譯器的主要組件
分析器
彙編器
鏈接器
標準C庫
GCC的基本用法和選項
-c | 只編譯,不連接成爲可執行文件.c到.o |
---|---|
-o | 確定輸出文件的名稱 |
-g | 產生符號調試工具(gdb) |
-O | 對程序進行優化編譯、連接 |
-O2 | 比-o更好的優化編譯、連接 |
-I dirname | 將dirname所指出的目錄加入到程序頭文件目錄列表中,是在預編譯過程中使用的參數 |
-L dirname | 將dirname所指出的目錄加入到程序函數檔案庫文件的目錄列表中,是在鏈接過程中使用的參數。 |
GCC的錯誤
-
語法錯誤(syntex error)
-
頭文件錯誤(Can no find include file head.h)
-
檔案庫錯誤(ld: -lm: No such file or directory)
-
未定義符號(Undefined symbol)
GCC編譯過程
-
預處理(Pre-Processing)
-
編譯(Compiling)
-
彙編(Assembling)
-
鏈接(Linking)
生成預處理代碼
$gcc -E test.c -o test.i
生成彙編代碼
$gcc -S test.i -o test.s
生成目標代碼
$gcc -c test.s -o test.o
$as test.s -o test.o
生成可執行程序
將目標程序鏈接庫資源,生成可執行程序
gcc test.s -o test
./test
調試器——gdb
首先使用gcc對test.c進行編譯,注意一定要加選項‘-g’
$gcc -g test.c -o test
gdb test
(gdb) l | 查看文件 |
---|---|
(gdb) b 6 | 設置斷點 |
(gdb) info b | 查看斷點情況 |
(gdb) r | 運行代碼 |
(gdb) p n | 查看變量值 |
(gdb) n /(gdb) s | 單步運行 |
(gdb) c | 恢復程序運行 |
(gdb) help [command] | 幫助 |
Gdb的使用切記點
在gcc編譯選項中一定要加入’-g’
只有在代碼處於“運行”或“暫停”狀態時才能查看變量值
設置斷點後程序在指定行之前停止