Linux基礎命令-SHELL腳本編程基礎

SHELL腳本編程基礎

一、編程基礎

1. 編程基礎

1Linus:Talk is cheap, show me the code
2程序
	程序:算法+數據結構
	數據:是程序的核心
	數據結構:數據在計算機中的類型和組織方式
	算法:處理數據的方式
3.程序編程風格:
	過程式:以指令爲中心,數據服務於指令
	對象式:以數據爲中心,指令服務於數據
4.shell程序:提供了編程能力,解釋執行

2. 程序的執行方式

1.計算機:運行二進制指令
2.編程語言:人與計算機之間交互的語言
3.低級編程語言:
	機器:二進制的01的序列,稱爲機器指令。與自然語言差異太大,難懂、難寫
	彙編:用一些助記符號替代機器指令,稱爲彙編語言
		如:ADD A,B 將寄存器A的數與寄存器B的數相加得到的數放到寄存器A中
		彙編語言寫好的程序需要彙編程序轉換成機器指令
		彙編語言稍微好理解,即機器指令對應的助記符,助記符更接近自然語言
4.高級編程語言:
	編譯:高級語言-->編譯器-->機器代碼-->執行
		CC++
	解釋:高級語言-->執行-->解釋器-->機器代碼
		shell,python,php,JavaScript,perl

3. 編譯和解釋型語言

在這裏插入圖片描述

4. 編程基本概念

1.編程邏輯處理方式:
	順序執行
	循環執行
	選擇執行
2.shell編程:過程式、解釋執行
	編程語言的基本結構:
	 各種系統命令的組合
	 數據存儲:變量、數組
	 表達式:a + b
	 語句:if 

二、腳本基本格式

1. shell腳本基礎

1.shell腳本:
	包含一些命令或聲明,並符合一定格式的文本文件
2.格式要求:首行shebang機制
	#!/bin/bash
	#!/usr/bin/python
	#!/usr/bin/perl
3.shell腳本的用途有:
	自動化常用命令
	執行系統管理和故障排除
	創建簡單的應用程序
	處理文本或文件

2. 創建shell腳本

1.第一步:使用文本編輯器來創建文本文件
	第一行必須包括shell聲明序列:#!
		示例:#!/bin/bash
	添加註釋
 		註釋以#開頭
2.第二步:運行腳本
	給予執行權限,在命令行上指定腳本的絕對或相對路徑
	直接運行解釋器,將腳本作爲解釋器程序的參數運行

3. 腳本規範

腳本代碼開頭約定
1、第一行一般爲調用使用的語言
2、程序名,避免更改文件名爲無法找到正確的文件
3、版本號
4、更改後的時間
5、作者相關信息
6、該程序的作用,及注意事項
7、最後是各版本的更新簡要說明

4. 編程基本概念

腳本的基本結構
#!SHEBANG
CONFIGURATION_VARIABLES
FUNCTION_DEFINITIONS
MAIN_CODE

5. shell腳本示例

#!/bin/bash
# ------------------------------------------
# Filename: hello.sh
# Revision: 1.1
# Date: 2017/06/01
# Author: wang
# Email: wang@gmail.com
# Website: www.magedu.com
# Description: This is the first script
# Copyright: 2017 wang
# License: GPL
# ------------------------------------------
echo “hello world”
[root@centos7 ~]# vim .vimrc
set ignorecase
set cursorline
set autoindent
autocmd BufNewFile *.sh exec ":call SetTitle()"
func SetTitle()
 if expand("%:e") == 'sh'
 call setline(1,"#!/bin/bash")
 call setline(2,"#****************
 ****************************************************")
 call setline(3,"#Filename: ".expand(("%")))
 call setline(4,"#Revision: 1.0")
 call setline(5,"#Date: ".strftime("%Y-%m-%d"))                                                                                       
 call setline(6,"#Author:zjl ")
 call setline(7,"#Email:[email protected]")
 call setline(8,"#Website:https://zjl.com")
 call setline(9,"#Description: Annotated script")
 call setline(10,"#********************************************************************")
 call setline(11,"")
endif
endfunc
autocmd BufNewFile * normal G

6. 腳本調試

1.檢測腳本中的語法錯誤
	bash -n /path/to/some_script
2.調試執行
	bash -x /path/to/some_script

三、變量

1. 變量

1.變量:命名的內存空間
2.變量:變量類型
	作用:
		1、數據存儲方式
		2、參與的運算
		3、表示的數據範圍
	類型:
		字符
		數值:整型、浮點型
3.Shell中變量命名法則:
	1、不能使程序中的保留字:例如if, for
	2、只能使用數字、字母及下劃線,且不能以數字開頭
	3、見名知義
	4、統一命名規則:駝峯命名法
4.Shell中命名建議規則:
	1、變量名大寫
	2、局部變量小寫
	3、函數名小寫
	4、用英文名字,並體現出實際作用
5.靜態編譯語言:使用變量前,先聲明變量類型,之後類型不能改變,在編譯時
  檢查,如:java,c
6.動態編譯語言:不用事先聲明,可隨時改變類型,如bash,Python
7.強類型語言:不同類型數據操作,必須經過強制轉換才同一類型才能運算,如
  java , c# ,python
	如:以下python代碼
	print(‘magedu’+ 10) 提示出錯,不會自動轉換類型
	print(‘magedu’+str(10)) 結果爲magedu10,需要顯示轉換類型
8.弱類型語言:語言的運行時會隱式做數據類型轉換。無須指定類型,默認均爲
  字符型;參與運算會自動進行隱式類型轉換;變量無須事先定義可直接調用
	如:bash 不支持浮點數,php,javascript

在這裏插入圖片描述

2. bash中變量的種類

根據變量的生效範圍等標準劃分下面變量類型
	局部變量:生效範圍爲當前shell進程;對當前shell之外的其它shell進程,包括當前shell的子shell進程均無效
	環境變量:生效範圍爲當前shell進程及其子進程
	本地變量:生效範圍爲當前shell進程中某代碼片斷,通常指函數
	位置變量:$1, $2, ...來表示,用於讓腳本在腳本代碼中調用通過命令行傳遞給它的參數
	特殊變量:$?, $0, $*, $@, $#,$$

a. 局部變量

1.變量賦值:name=‘value’
2.可以使用引用value
	(1) 可以是直接字串:name=“root"
	(2) 變量引用:name="$USER"
	(3) 命令引用:name=`COMMAND`
				  name=$(COMMAND)
3.變量引用:${name} 或者 $name
	" " 弱引用,其中的變量引用會被替換爲變量值
	' ' 強引用,其中的變量引用不會被替換爲變量值,而保持原字符串
4.顯示已定義的所有變量:set
5.刪除變量:unset name

b. 環境變量

1.變量聲明、賦值:
	export name=VALUE
	declare -x name=VALUE
2.變量引用:
	$name, ${name}
3.顯示所有環境變量:
	env
	printenv
	export
	declare -x
4.刪除變量:
	unset name
5.bash內建的環境變量
	PATH
	SHELL
	USER
	UID
	HOME
	PWD
	SHLVL
	LANG
	MAIL
	HOSTNAME
	HISTSIZE
	_ 下劃線

c. 只讀和位置變量

1.只讀變量:只能聲明,但不能修改和刪除
	聲明只讀變量:
		readonly name
		declare -r name
	查看只讀變量:
		readonly -p
2.位置變量:在腳本代碼中調用通過命令行傳遞給腳本的參數
	$1, $2, ... 對應第1、第2等參數,shift [n]換位置
	$0 命令本身
	$* 傳遞給腳本的所有參數,全部參數合爲一個字符串
	$@ 傳遞給腳本的所有參數,每個參數爲獨立字符串
	$# 傳遞給腳本的參數的個數
	 注意:$@ $* 只在被雙引號包起來的時候纔會有差異
	set -- 清空所有位置變量

3. 退出狀態

1.進程使用退出狀態來報告成功或失敗
	0 代表成功,1255代表失敗
	$? 變量保存最近的命令退出狀態
2.例如:
	ping -c1 -W1 hostdown &> /dev/null
	echo $?

4. 退出狀態碼

bash自定義退出狀態碼
	exit [n]:自定義退出狀態碼
	注意:腳本中一旦遇到exit命令,腳本會立即終止;終止退出狀態取決於exit命
令後面的數字
	注意:如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決於腳本中執
行的最後一條命令的狀態碼

四、運算

1. 算術運算

1.bash中的算術運算:help let
	+, -, *, /, %取模(取餘), **(乘方),乘法符號有些場景中需要轉義
	實現算術運算:
		(1) let var=算術表達式
		(2) var=$[算術表達式]
		(3) var=$((算術表達式))
		(4) var=$(expr arg1 arg2 arg3 ...)
		(5) declare –i var = 數值
		(6) echo ‘算術表達式’ | bc
2.bash有內建的隨機數生成器變量:$RANDOM0-32767)
	示例:生成 0 - 49 之間隨機數
	echo $[$RANDOM%50]

2. 賦值

1.增強型賦值:
	+=, -=, *=, /=, %=
2.let varOPERvalue
	例如:let count+=3
	     自加3後自賦值
3.自增,自減:
	let var+=1
	let var++
	let var-=1
	let var

3. 邏輯運算

1.true, false
	1, 0
2.11 = 1
	10 = 0
	01 = 0
	00 = 0
3.11 = 1
	10 = 1
	01 = 1
	00 = 0
4.非:!
	! 1 = 0 ! true
	! 0 = 1 ! false
5.短路運算
	短路與
		第一個爲0,結果必定爲0
		第一個爲1,第二個必須要參與運算
	短路或
		第一個爲1,結果必定爲1
		第一個爲0,第二個必須要參與運算
6.異或:^
	異或的兩個值,相同爲假,不同爲真

五、條件測試

1. 條件測試

1.判斷某需求是否滿足,需要由測試機制來實現
	專用的測試表達式需要由測試命令輔助完成測試過程
2.評估布爾聲明,以便用在條件性執行中
	• 若真,則返回0
	• 若假,則返回1
3.測試命令:
	• test EXPRESSION[ EXPRESSION ][[ EXPRESSION ]]
	 注意:EXPRESSION前後必須有空白字符

2. bash的數值測試

-v VAR
	變量VAR是否設置
數值測試:
	-gt 是否大於
	-ge 是否大於等於
	-eq 是否等於
	-ne 是否不等於
	-lt 是否小於
	-le 是否小於等於

3. bash的字符串測試

1.字符串測試:
	= 是否等於
	> ascii碼是否大於ascii碼
	< 是否小於
	!= 是否不等於
	=~ 左側字符串是否能夠被右側的PATTERN所匹配
		 注意: 此表達式一般用於[[ ]]中;擴展的正則表達式
	 -z "STRING“ 字符串是否爲空,空爲真,不空爲假
	 -n "STRING“ 字符串是否不空,不空爲真,空爲假
2.注意:用於字符串比較時的用到的操作數都應該使用引號

4. bash的文件測試

1.存在性測試
	-a FILE:同 -e
	-e FILE: 文件存在性測試,存在爲真,否則爲假
2.存在性及類別測試
	-b FILE:是否存在且爲塊設備文件
	-c FILE:是否存在且爲字符設備文件
	-d FILE:是否存在且爲目錄文件
	-f FILE:是否存在且爲普通文件
	-h FILE-L FILE:存在且爲符號鏈接文件
	-p FILE:是否存在且爲命名管道文件
	-S FILE:是否存在且爲套接字文件

5. bash的文件權限測試

1.文件權限測試:
	-r FILE:是否存在且可讀
	-w FILE: 是否存在且可寫
	-x FILE: 是否存在且可執行
2.文件特殊權限測試:
	-u FILE:是否存在且擁有suid權限
	-g FILE:是否存在且擁有sgid權限
	-k FILE:是否存在且擁有sticky權限

6. bash的文件屬性測試

1.文件大小測試:
	-s FILE: 是否存在且非空
2.文件是否打開:
	-t fd: fd 文件描述符是否在某終端已經打開
	-N FILE:文件自從上一次被讀取之後是否被修改過
	-O FILE:當前有效用戶是否爲文件屬主
	-G FILE:當前有效用戶是否爲文件屬組
3.雙目測試:
	FILE1 -ef FILE2: FILE1是否是FILE2的硬鏈接
	FILE1 -nt FILE2: FILE1是否新於FILE2(mtime)
	FILE1 -ot FILE2: FILE1是否舊於FILE2

7. bash的組合測試條件

1.第一種方式:
	EXPRESSION1 -a EXPRESSION2 並且
	EXPRESSION1 -o EXPRESSION2 或者
	! EXPRESSION
	必須使用測試命令進行,[[ ]] 不支持
2.第二種方式:
	COMMAND1 && COMMAND2 並且,短路與,代表條件性的AND THEN
	COMMAND1 || COMMAND2 或者,短路或,代表條件性的OR ELSE
	! COMMAND 非
	如:[ -f “$FILE] && [[ “$FILE=~ .*\.sh$ ]]
3.示例:
	grep -q no_such_user /etc/passwd || echo 'No such user'
	No such user
	ping -c1 -W2 station1 &> /dev/null \
	> && echo "station1 is up" \
	> || (echo 'station1 is unreachable'; exit 1)
	station1 is up
4.示例:
	test "$A" = "$B" && echo "Strings are equal"
	test “$A-eq “$B&& echo "Integers are equal“
	[ "$A" = "$B" ] && echo "Strings are equal"
	[ "$A" -eq "$B" ] && echo "Integers are equal“
	[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab
	[ -z “$HOSTNAME-o $HOSTNAME "=="localhost.localdomain" ] \
	&& hostname www.magedu.com
	
	##	[ $RANDOM%6 –eq 0 ] && rm –rf /* || echo “click”

8. 使用read命令來接受輸入

1.使用read來把輸入值分配給一個或多個shell變量
	-p 指定要顯示的提示
	-s 靜默輸入,一般用於密碼
	-n N 指定輸入的字符長度N
	-d ‘字符’ 輸入結束符
	-t N TIMEOUTN秒
	read 從標準輸入中讀取值,給每個單詞分配一個變量
	所有剩餘單詞都被分配給最後一個變量
	read -p “Enter a filename:FILE

六、條件判斷if

1. 條件判斷if

1.選擇執行:
2.注意:if語句可嵌套
3.單分支
	if 判斷條件;then
		條件爲真的分支代碼
	fi
2.雙分支
	if 判斷條件; then
		條件爲真的分支代碼
	else
		條件爲假的分支代碼
	fi
3.多分支
	if 判斷條件1; then
		條件1爲真的分支代碼
	elif 判斷條件2; then
		條件2爲真的分支代碼
	elif 判斷條件3; then
		條件3爲真的分支代碼
	else
		以上條件都爲假的分支代碼
	fi
4.逐條件進行判斷,第一次遇爲“真”條件時,執行其分支,而後結束整個if語句
5.根據命令的退出狀態來執行命令
	if ping -c1 -W2 station1 &> /dev/null; then
		echo 'Station1 is UP'
	elif grep "station1" ~/maintenance.txt &> /dev/null; then
		echo 'Station1 is undergoing maintenance'
	else
		echo 'Station1 is unexpectedly DOWN!'
		exit 1
	fi

七、條件判斷case

1. 條件判斷:case語句

	case 變量引用 in
	PAT1)
		分支1
		;;
	PAT2)
		分支2
		;;
	...
	*)
		默認分支
		;;
	esac
	
case支持glob風格的通配符:
	*: 任意長度任意字符
	?: 任意單個字符
	[]:指定範圍內的任意單個字符
	a|b: a或b

八、配置用戶環境

1. bash如何展開命令行

1.把命令行分成單個命令詞
2.展開別名
3.展開大括號的聲明({}4.展開波浪符聲明(~5.命令替換$()``6.再次把命令行分成命令詞
7.展開文件通配(*?[abc]等等)
8.準備I/0重導向(<>9.運行命令

2. 防止擴展

1.反斜線(\)會使隨後的字符按原意解釋
	echo Your cost: \$5.00
	Your cost: $5.00
2.加引號來防止擴展
	• 單引號(’’)防止所有擴展
	• 雙引號(”“)也可防止擴展,但是以下情況例外:
		$(美元符號) 變量擴展
		` ` (反引號) 命令替換
		\(反斜線) 禁止單個字符擴展
		!(歎號) 歷史命令替換

3. bash的配置文件

1.按生效範圍劃分,存在兩類:
2.全局配置:
	/etc/profile
	/etc/profile.d/*.sh
	/etc/bashrc
3.個人配置:
	~/.bash_profile
	~/.bashrc

4. shell登錄兩種方式

1.交互式登錄:
	(1)直接通過終端輸入賬號密碼登錄
	(2)使用“su - UserName” 切換的用戶
	執行順序:/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile -->
~/.bashrc --> /etc/bashrc                 */
2.非交互式登錄:
	(1)su UserName
	(2)圖形界面下打開的終端
	(3)執行腳本
	(4)任何其它的bash實例
	執行順序: /etc/profile.d/*.sh --> /etc/bashrc -->~/.bashrc

5. Profile類

1.按功能劃分,存在兩類:
	profile類和bashrc類
2.profile類:爲交互式登錄的shell提供配置
	全局:/etc/profile, /etc/profile.d/*.sh  						 */
	個人:~/.bash_profile
	功用:
		(1) 用於定義環境變量
		(2) 運行命令或腳本

6. Bashrc類

bashrc類:爲非交互式和交互式登錄的shell提供配置
	全局:/etc/bashrc
	個人:~/.bashrc
	功用:
		(1) 定義命令別名和函數
		(2) 定義本地變量

7. 編輯配置文件生效

修改profile和bashrc文件後需生效
	兩種方法:
	1重新啓動shell進程
	2 . 或source
	例:
		. ~/.bashrc

8. Bash 退出任務

1.保存在~/.bash_logout文件中(用戶)
2.在退出登錄shell時運行
3.用於
	• 創建自動備份
	• 清除臨時文件

9. set 命令

$- 變量
h:hashall,打開這個選項後,Shell 會將命令所在的路徑hash下來,避免每次
   都要查詢。通過set +h將h選項關閉
i:interactive-comments,包含這個選項說明當前的 shell 是一個交互式的
   shell。所謂的交互式shell,在腳本中,i選項是關閉的。
m:monitor,打開監控模式,就可以通過Job control來控制進程的停止、繼
   續,後臺或者前臺執行等。
B:braceexpand,大括號擴展
H:history,H選項打開,可以展開歷史列表中的命令,可以通過!感嘆號來完
   成,例如“!!”返回上最近的一個歷史命令,“!n”返回第 n 個歷史命令

10. 腳本安全

set 命令
	-u 在擴展一個沒有設置的變量時,顯示錯誤信息
		 等同set –o nounset
	-e 如果一個命令返回一個非0退出狀態值(失敗)就退出
		 等同set –o errexit
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章