bash


前文:VIM的用法


bash的基礎特性:

一、

命令歷史:shell進程會其會話中保存此前用戶提交執行過的命令;

~]# history

定製history的功能,可通過環境變量實現:

HISTSIZE:shell進程可保留的命令歷史的條數;

HISTFILE:持久保存命令歷史的文件;

.bash_history

HISTFILESIZE:命令歷史文件的大小;


命令用法:

history [-c] [-d 偏移量] [n] 

或 history -anrw [文件名] 

或 history -ps 參數 [參數...]


-c: 清空命令歷史;

-d offset:刪除指定命令歷史

-r: 從文件讀取命令歷史至歷史列表中;

-w:把歷史列表中的命令追加至歷史文件中;

history #:顯示最近的#條命令;


調用命令歷史列表中的命令:

!#:再一次執行歷史列表中的第#條命令;

!!:再一次執行上一條命令;

!STRING:再一次執行命令歷史列表中最近一個以STRING開頭的命令;


注意:命令的重複執行有時候需要依賴於冪等性;


調用上一條命令的最後一個參數:

快捷鍵:ESC, .

字符串:!$


控制命令歷史記錄的方式:

環境變量:HISTCONTROL

ignoredups:忽略重複的命令;

ignorespace:忽略以空白字符開頭的命令;

ignoreboth:以上兩者同時生效;


修改變量的值:

NAME='VALUE'

二、命令補全:

shell程序在接收到用戶執行命令的請求,分析完成之後,最左側的字符串會被當作命令;

命令查找機制:

查找內部命令;

根據PATH環境變量中設定的目錄,自左而右逐個搜索目錄下的文件名;


給定的打頭字符串如果能惟一標識某命令程序文件,則直接補全;

                    不能惟一標識某命令程序文件,再擊tab鍵一次,會給出列表;


三、路徑補全:

在給定的起始路徑下,以對應路徑下的打頭字串來逐一匹配起始路徑下的每個文件:

tab:

如果能惟一標識,則直接補全;

否則,再一次tab,給出列表;

四、命令行展開

~:自動展開爲用戶的家目錄,或指定的用戶的家目錄;

{}:可承載一個以逗號分隔的路徑列表,並能夠將其展開爲多個路徑;

例如:/tmp/{a,b} 相當於 /tmp/a /tmp/b

五、命令的執行狀態結果


命令執行的狀態結果:

bash通過狀態返回值來輸出此結果:

成功:0

失敗:1-255


命令執行完成之後,其狀態返回值保存於bash的特殊變量$?中;


命令正常執行時,有的還回有命令返回值:

根據命令及其功能不同,結果各不相同;


引用命令的執行結果:

$(COMMAND)

或`COMMAND`


六、引用

強引用:''

弱引用:""

命令引用:``

七、快捷鍵

Ctrl+a:跳轉至命令行行首

Ctrl+e:跳轉至命令行行尾


Ctrl+u:刪除行首至光標所在處之間的所有字符;

Ctrl+k:刪除光標所在處至行尾的所有字符;


Ctrl+l:清屏,相當於clear

八、globbing:文件名通配(整體文件名匹配,而非部分)


匹配模式:元字符

*:匹配任意長度的任意字符

pa*, *pa*, *pa, *p*a*

pa, paa, passwd

?:匹配任意單個字符

pa?, ??pa, p?a, p?a?

pa, paa, passwd

[]:匹配指定範圍內的任意單個字符

有幾種特殊格式:

[a-z], [A-Z], [0-9], [a-z0-9]

[[:upper:]]:所有大寫字母

[[:lower:]]:所有小寫字母

[[:alpha:]]:所有字母

[[:digit:]]:所有數字

[[:alnum:]]:所有的字母和數字

[[:space:]]:所有空白字符

[[:punct:]]:所有標點符號


pa[0-9][0-9], 2[0-9][0-9]

[^]:匹配指定範圍外的任意單個字符

[^[:upper:]]

[^0-9]

[^[:alnum:]]

九、IO重定向及管道


程序:指令+數據

程序:IO


可用於輸入的設備:文件

鍵盤設備、文件系統上的常規文件、網卡等;

可用於輸出的設備:文件

顯示器、文件系統上的常規文件、網卡等;


程序的數據流有三種:

輸入的數據流;<-- 標準輸入(stdin),鍵盤;

輸出的數據流:--> 標準輸出(stdout),顯示器;

錯誤輸出流:  --> 錯誤輸出(stderr),顯示器;


fd: file descriptor,文件描述符

標準輸入:0

標準輸出:1

錯誤輸出:2


IO重定向:


輸出重定向:>

特性:覆蓋輸出

輸出重定向:>>

特性:追加輸出


# set -C

禁止覆蓋輸出重定向至已存在的文件;

此時可使用強制覆蓋輸出:>|

# set +C

關閉上述特性


錯誤輸出流重定向:2>, 2>>


合併正常輸出流和錯誤輸出流:

(1) &>, &>>

(2) COMMAND > /path/to/somefile 2>&1

    COMMAND >> /path/to/somefile 2>&1


特殊設備:/dev/null


輸入重定向:<


tr命令:

tr [OPTION]... SET1 [SET2]

把輸入的數據當中的字符,凡是在SET1定義範圍內出現的,通通對位轉換爲SET2出現的字符


用法1:

tr SET1 SET2 < /PATH/FROM/SOMEFILE

用法2:

tr -d SET1 < /PATH/FROM/SOMEFILE


注意:不修改原文件


Here Document:<<


cat << EOF

cat > /PATH/TO/SOMEFILE << EOF


管道:連接程序,實現將前一個命令的輸出直接定向後一個程序當作輸入數據流

COMMAND1 | COMMAND2 | COMMAND3 | ...


tee命令:

COMMAND | tee /PATH/TO/SOMEFILE



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進程實現的;

練習1:寫一個腳本,實現如下功能;

(1) 顯示/etc目錄下所有以大寫p或小寫p開頭的文件或目錄本身;

(2) 顯示/var目錄下的所有文件或目錄本身,並將顯示結果中的小寫字母轉換爲大寫後顯示;

(3) 創建臨時文件/tmp/myfile.XXXX;

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

問題1:定義對所有用戶都生效的命令別名,例如 lftps='lftp 172.16.0.1/pub'?

問題2:讓centos用戶登錄時,提供其已經登錄,並顯示當前系統時間?

回顧:

bash的特性:hash, 變量

命令hash:hash命令

變量:

本地變量、環境變量、局部變量

位置參數變量、特殊變量

變量賦值:name=value, export name=value, declare -x name=value

變量引用:$name, ${name}

撤銷:unset name

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


練習:定義一個對所有用戶都生效的命令別名,例如:lftps='lftp 172.168.0.1/pub'

                    alias.png

二、編寫腳本,實現自動添加三個用戶,並計算這三個用戶的uid之和。

                        三週useradd.png



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章