一、編程基礎概念:
- 程序編程風格:
- 面向過程:以指令為中心,數據服務于指令,適于開發小型程序
- 面向對象:以數據為中心,指令服務于數據,適于開發大型程序
- shell程序采用面向過程思想開發,命令解釋執行
- 編程語言分類:
- 低級語言:匯編
- 高級語言:按照程序執行方式分:
- 編譯執行:C,Java等
- 解釋執行:python,shell等
- 編程邏輯處理方式:
- 順序執行
- 循環執行
- 選擇執行
- 編程語言基本結構:
- 系統命令組合
- 數據存儲
- 表達式
- 語句
二、shell腳本編程基礎
- shell腳本的用途:
- 自動化執行
- 系統管理、故障排除
- 創建簡單的應用程序
- 處理文本、文件
- 格式:
- 首行shebang機制:
#! /bin/bash
- #開頭的行表示注釋,一般在首行shebang后,使用注釋描述與程序相關的基本信息,如程序名、版本號、時間、作者、功能描述、更新內容簡述等
- 首行shebang機制:
- 程序執行前必須為其增加執行權限
- 執行程序,三種方式:
程序絕對路徑
bash 程序路徑
-
程序名稱
,此時需要確保程序文件在PATH變量的路徑列表中,否則bash找不到程序文件
- 程序調試
- 檢查腳本語法錯誤
bash -n scriptname
- 調試執行
bash -x scriptname
- 檢查腳本語法錯誤
三、變量:命名的內存空間
(一)變量類型:數值型、字符型等
- 強類型:定義時必須指定變量類型,不允許隱式類型轉換,調用未聲明變量會發生錯誤,如C++,Java
- 弱類型:變量默認均為字符型,自動進行隱式類型轉換,無需提前定義可直接調用,如shell,php
(二)變量命名規則:
- 不能使用程序語言的保留字
- 只能使用字母、數字、下劃線的組合,并且不能以數字開頭
- 能從命名看出變量的意義
- 統一命名規則:駝峰命名法
- 大駝峰命名:每個單詞首字母大寫,如
StudentName
- 小駝峰命名:第一個單詞首字母小寫,其余單詞首字母大寫,如
teacherName
- 大駝峰命名:每個單詞首字母大寫,如
(三)bash變量的種類,根據變量的生效范圍分類:
- 本地變量:只對當前shell進程有效
- 局部變量:只在當前shell的某一個代碼片段中有效
- 環境變量:對當前shell及其子進程有效
- 位置變量:調用命令行傳遞的參數
- 特殊變量:系統規定的一些具有特定意義的變量
(四)本地變量:
- 賦值語法:
name='value'
- 賦值方式:
(1) 直接賦值,如name="root"
(2) 將變量值賦值,如username="$USER"
(3) 將命令的結果賦值,如date=$(date +%F)
,$()可以用一對反向單引號代替`` - 變量弱引用" ",雙引號內的變量引用會被替換為變量值
- 變量強引用' ',單引號內的變量引用會保持原樣的字符串
- 顯示已定義的所有變量:
set
- 刪除變量:
unset name
- 實驗:
1、創建兩個shell腳本名稱分別為father.sh和son.sh,兩個文件內容如下:
<!--father.sh的程序代碼-->
#! /bin/bash
#
name="father"
echo "the name in father.sh is $name"
bash son.sh
<!--son.sh的程序代碼-->
#! /bin/bash
#
echo "the name in son.sh is $name"
2、執行father.sh腳本,結果如下:
3、根據執行腳本的結果表明,執行son.sh的子進程沒有繼承到來自父進程的變量name,證明本地變量僅對當前的shell進程有效。
(五)環境變量
- 變量聲明、賦值語法:賦值方法與本地變量相同,使用
export
或declare -x
在賦值前聲明為環境變量,如export value=10
- 顯示所有環境變量:
export, declare -x, env, printenv
- bash內建環境變量:
PATH, SHELL, USER,UID, HOME, PWD, OLDPWD, HOSTNAME, HISTSIZE
等 - 實驗:
1、將上文的father.sh和son.sh腳本文件進行修改,修改后的腳本文件如下:
<!--father.sh的程序代碼-->
#! /bin/bash
#
export name="father"
echo "the name in father.sh is $name"
bash son.sh
<!--son.sh的程序代碼-->
#! /bin/bash
#
echo "the name in son.sh is $name"
2、執行father.sh腳本,結果如下:
3、根據執行腳本的結果表明,執行son.sh的子進程繼承到來自父進程的變量name,證明環境變量對當前的shell進程及其子進程有效。
(六)只讀變量
- 變量聲明、賦值語法:賦值方法與本地變量相同,使用
readonly
或declare -r
在賦值前聲明為只讀變量,如readonly pi=3.1415926
- 查看只讀變量:
readonly -p
- 只讀變量定義后不能修改、不能刪除,隨所在進程的結束而清除
-
實驗:
(七)位置變量和特殊變量
- $1, $2, ...:對應第1、第2個參數
- shift [n]:所有參數向左移動n位,$1至$n拋棄
- $0:命令本身
- $*:傳遞給腳本的所有參數,全部參數合為一個字符串
- $@:傳遞給腳本的所有參數,每個參數為獨立字符串
- $#:傳遞給腳本的參數的個數
- set --:清空所有位置變量
- $?:最近命令的退出狀態,0代表成功執行,1-255代表出現錯誤
- 實驗:
實驗(一)
1、編寫腳本文件parent.sh,代碼如下:
#! /bin/bash
#
echo "the 1st number is $1"
echo "the 2nd number is $2"
echo "the 3rd number is $3"
echo "the 10st number is $10"
echo "the 20st number is $20"
echo "the 35st number is $35"
echo "the 1st number is $1"
echo "the 2nd number is $2"
echo "the 3rd number is $3"
echo "the 10st number is ${10}"
echo "the 20st number is ${20}"
echo "the 35st number is ${35}"
2、執行命令
bash parent.sh `echo {1..100..2}`
結果如下:
地址變量1.png
3、發現結果不同,這是因為$10表達的意思是地址變量$1的值和字符0,${10}表達的意思是第10個地址變量。使用地址變量時當超出10個時要注意加大括號。
實驗(二)
1、編寫腳本文件parent.sh,代碼如下:
#! /bin/bash
#
echo "the 1st number in parent.sh is $1"
echo "the 2nd number in parent.sh is $2"
echo "the 3rd number in parent.sh is $3"
echo "all of the number in parent.sh is $*"
echo "all of the number in parent.sh is $@"
echo
bash children.sh "$*"
echo
bash children.sh "$@"
2、編寫腳本文件children.sh,代碼如下:
# /bin/bash
#
echo "the 1st number in children.sh is $1"
echo "the 2nd number in children.sh is $2"
echo "the 3rd number in children.sh is $3"
echo "all of the number in children.sh is $*"
echo "all of the number in children.sh is $@"
3、執行命令bash parent.sh {1..10}
,結果如下
4、從結果發現$*
和$@
的作用有所不同,當其被雙引號括起來后,$*
把所有位置變量當做一個字符串整體傳給子進程,而$@
則是把每個位置變量分別傳給子進程。這導致子進程的變量值的輸出結果不同。