bash特性及bash腳本編程初步
終端,附着在終端的接口程序:
GUI:KDE, GNome, Xfce
CLI:/etc/shells
bash
zsh
fish
bash的特性:
命令行展開:~, {}
命令別名:alias, unalias
命令歷史:history
文件名通配:glob
快捷鍵:Ctrl+a, e, u, k, l
命令補全:$PATH
路徑補全:
bash特性之:命令hash
緩存此前命令的查找結果:key-value
key:搜索鍵
value:值
hash命令:
hash:列出
hash -d COMMAND:刪除
hash -r:清空
bash的特性之:變量
程序:指令+數據
指令:由程序文件提供;
數據:IO設備、文件、管道、變量
程序:算法+數據結構
變量名+指向的內存空間
變量賦值:name=value
變量類型:存儲格式、表示數據範圍、參與的運算
編程語言:
強類型變量
弱類型變量:
bash把所有變量統統視作字符型;
bash中的變量無需事先聲明;相當於,把聲明和賦值過程同時實現;
聲明:類型,變量名
變量替換:把變量名出現的位置替換爲其所指向的內存空間中數據;
變量引用:${var_name}, $var_name
變量名:變量名只能包含數字、字母和下劃線,而且不能以數字開頭;
變量名:見名知義,命名機制遵循某種法則;不能夠使用程序的保留字,例如if, else, then, while等等;
bash變量類型:
本地變量:作用域僅爲當前shell進程;
環境變量:作用域爲當前shell進程及其子進程;
局部變量:作用域僅爲某代碼片斷(函數上下文);
位置參數變量:當執行腳本的shell進程傳遞的參數;
特殊變量:shell內置的有特殊功用的變量;
$?:
0:成功
1-255:失敗
本地變量:
變量賦值:name=value
變量引用:${name}, $name
"":變量名會替換爲其值;
'':變量名不會替換爲其值;
查看變量:set
撤銷變量:unset name
注意:此處非變量引用;
環境變量:
變量賦值:
(1) export name=value
(2) name=value
export name
(3) declare -x name=value
(4) name=value
declare -x name
變量引用:${name}, $name
注意:bash內嵌了許多環境變量(通常爲全大寫字符),用於定義bash的工作環境
PATH, HISTFILE, HISTSIZE, HISTFILESIZE, HISTCONTROL, SHELL, HOME, UID, PWD, OLDPWD
查看環境變量:export, declare -x, printenv, env
撤銷環境變量:unset name
只讀變量:
(1) declare -r name
(2) readonly name
只讀變量無法重新賦值,並且不支持撤銷;存活時間爲當前shell進程的生命週期,隨shell進程終止而終止;
bash特性之多命令執行:
~]# COMMAND1; COMMAND2; COMMAND3; ...
邏輯運算:
運算數:真(true, yes, on, 1)
假(false, no, off, 0)
與:
1 && 1 = 1
1 && 0 = 0
0 && 1 = 0
0 && 0 = 0
或:
1 || 1 = 1
1 || 0 = 1
0 || 1 = 1
0 || 0 = 0
非:
! 1 = 0
! 0 = 1
短路法則:
~]# COMMAND1 && COMMAND2
COMMAND1爲“假”,則COMMAND2不會再執行;
否則,COMMAND1爲“真”,則COMMAND2必須執行;
~]# COMMAND1 || COMMAND2
COMMAND1爲“真”,則COMMAND2不會再執行;
否則,COMMAND1爲“假”,則COMMAND2必須執行;
示例:~]# id $username || useradd $username
shell腳本編程:
編程語言的分類:根據運行方式
編譯運行:源代碼 --> 編譯器 (編譯)--> 程序文件;
解釋運行:源代碼 --> 運行時啓動解釋器,由解釋器邊解釋邊運行;
根據其編程過程中功能的實現是調用庫還是調用外部的程序文件:
shell腳本編程:
利用系統上的命令及編程組件進行編程;
完整編程:
利用庫或編程組件進行編程;
編程模型:過程式編程語言,面向對象的編程語言
程序=指令+數據
過程式:以指令爲中心來組織代碼,數據是服務於代碼;
順序執行
選擇執行
循環執行
代表:C,bash
對象式:以數據爲中心來組織代碼,圍繞數據來組織指令;
類(class):實例化對象,method;
代表:Java, C++, Python
shell腳本編程:過程式編程,解釋運行,依賴於外部程序文件運行;
如何寫shell腳本:
腳本文件的第一行,頂格:給出shebang,解釋器路徑,用於指明解釋執行當前腳本的解釋器程序文件
常見的解釋器:
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
文本編程器:nano
行編輯器:sed
全屏幕編程器:nano, vi, vim
shell腳本是什麼?
命令的堆積;
但很多命令不具有冪等性,需要用程序邏輯來判斷運行條件是否滿足,以避免其運行中發生錯誤;
運行腳本:
(1) 賦予執行權限,並直接運行此程序文件;
chmod +x /PATH/TO/SCRIPT_FILE
/PATH/TO/SCRIPT_FILE
(2) 直接運行解釋器,將腳本以命令行參數傳遞給解釋器程序;
bash /PATH/TO/SCRIPT_FILE
注意:腳本中的空白行會被解釋器忽略;
腳本中,除了shebang,餘下所有以#開頭的行,都會被視作註釋行而被忽略;此即爲註釋行;
shell腳本的運行是通過運行一個子shell進程實現的;
bash的配置文件:
兩類:
profile類:爲交互式登錄的shell進程提供配置
bashrc類:爲非交互式登錄的shell進程提供配置
登錄類型:
交互式登錄shell進程:
直接通過某終端輸入賬號和密碼後登錄打開的shell進程;
使用su命令:su - USERNAME, 或者使用 su -l USERNAME執行的登錄切換;
非交互式登錄shell進程:
su USERNAME執行的登錄切換;
圖形界面下打開的終端;
運行腳本
profile類:
全局:對所有用戶都生效;
/etc/profile
/etc/profile.d/*.sh
用戶個人:僅對當前用戶有效;
~/.bash_profile
功用:
1、用於定義環境變量;
2、運行命令或腳本;
bashrc類:
全局:
/etc/bashrc
用戶個人:
~/.bashrc
功用:
1、定義本地變量;
2、定義命令別名;
注意:僅管理員可修改全局配置文件;
交互式登錄shell進程:
/etc/profile --> /etc/profile.d/* --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc
非交互式登錄shell進程:
~/.bashrc --> /etc/bashrc --> /etc/profile.d/*
命令行中定義的特性,例如變量和別名作用域爲當前shell進程的生命週期;
配置文件定義的特性,只對隨後新啓動的shell進程有效;
讓通過配置文件定義的特性立即生效:
(1) 通過命令行重複定義一次;
(2) 讓shell進程重讀配置文件;
~]# source /PATH/FROM/CONF_FILE
~]# . /PATH/FROM/CONF_FILE
bash腳本編程,運行腳本
#!/bin/bash
#
bash的配置文件
profile類:登錄式shell
bashrc類:非登錄式shell
登錄式shell: /etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc
非登錄式shell:~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh
bash腳本編程之算術運算
+,-,*,/, **, %
算術運算格式:
(1) let VAR=算術運算表達式
(2) VAR=$[算術運算表達式]
(3) VAR=$((算術運算表達式))
(4) VAR=$(expr $ARG1 $OP $ARG2)
注意:乘法符號在有些場景中需要使用轉義符;