Linux shell之bash特性大全詳解(持續更新ing)

一、shell是什么?

    Shell本身是一個用C語言編寫的程序,它是用戶使用Unix/Linux的橋梁,用戶的大部分工作都是通過Shell完成的。Shell既是一種命令語言,又是一種程序設計語言。作為命令語言,它交互式地解釋和執行用戶輸入的命令;作為程序設計語言,它定義了各種變量和參數,并提供了許多在高級語言中才具有的控制結構,包括循環和分支。

    如圖shell是一個應用程序,是用戶管理應用程序的一個接口。

wKioL1ba5wXDNSCsAABtio430hE601.png

二、廣義上shell的分類

    GUI:圖形用戶界面

        KDE,GNOME,XFCE

    CLI:命令行接口

        bash, zsh, fishsh, csh, tcsh, ksh

在大多發行版中常用的為bash

三、bash的特性

bash是弱類型的編程語言,不嚴格區分數據類型,意味把所有數據統統當作字符串處理;

字符串類型的數據可不加引號; 

引號有三種類型:', ", `

', ":字符引用

': 強引用,其內部的變量不會被替換; 

":弱引用,其內部的變量會被替換;

`:命令引用

變量引用:${NAME}

a、bash特性之一:命令別名

    獲取當前用戶可用的別名的定義:

# alias

    定義別名:

# alias  NAME='COMMAND'

    生命周期:當前shell進程;

    撤消別名:

# unalias NAME

b、bash的特性之二:命令歷史

    shell進程會保存其會話中用戶曾經執行過的命令;命令通過其“歷史文件”來持久保存此前執行過的命令;每個用戶都有其自己專用的歷史文件;

HISTSIZE:shell進程的緩沖區保留的歷史命令的條數;

HISTFILESIZE:命令歷史文件可保存的歷史命令的條數;

    默認均為1000;       

# echo $HISTSIZE
1000
# echo $HISTFILESIZE
1000

        HISTFILE:當前用戶的命令歷史文件;

    ~/.bash_history

查看命令歷史列表:

# history

    命令用法:

history -c:清空命令歷史;

history  -d  OFFSET:刪除指定的條目;

# history -d 156

    -a        將當前緩沖的歷史行追加到歷史文件中

    -n        從歷史文件中讀取所有未被讀取的行

    -r        讀取歷史文件并將內容追加到歷史列表中

調用命令歷史列表中的命令以重執行之目的:

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

# history
   ....
   72  cat test 
   73  history 
# !72
cat test 
Hello World

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

# cat test 
Hello World
# !!
cat test 
Hello World

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

# !cat
cat test 
Hello World

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

快捷鍵:ESC, .

                     Alt+.

!$:給出的字符組合

    顯示最近的n條件命令歷史:

    history  #

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

通過HISTCONTROL環境變量進行,其取值:

    ignoredups:忽略重復的命令;重復是指連續且相同的令;

    ignorespace:以空白字符開頭的命令不記入歷史;

    ignoreboth:上述兩者同時生效;

        修改變量值的方式:

    NAME='VALUE'

# echo $HISTCONTROL
ignoredups
# HISTCONTROL="ignoreboth"
# echo $HISTCONTROL
ignoreboth

c、bash特性之三:快捷鍵 

Ctrl+a:跳至命令行首;

Ctrl+e:跳至命令行尾;

Ctrl+k:刪除光標所在處至尾部的內容;

Ctrl+u:刪除行首至光標所在處的內容;

d、bash的特性之四:命令補全和路徑補全

    命令補全:

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

      查找機制:

(1) 查找內部命令;

(2) 查找外部命令:

    1、去$PATH變量所指定的各路徑下,自左而右逐個搜索各目錄下的文件名;

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

    3、不能惟一標識,再擊tab可給列表;

    4、錯誤:沒有任何命令可被此打頭字符串標識;

       路徑補全:

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

惟一標識:tab補全;

不能惟一標識:tab, tab給出列表;

錯誤路徑:沒有響應;

e、bash的特性之五:命令行展開:

    把命令行的給定的特殊符號自動替換為相應字符串的機制;

~: 自動替換為用戶家目錄;

~USERNAME:自動替換為指定用戶的家目錄;

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

            例如:

                /tmp/{a,b,c} /tmp/a /tmp/b /tmp/c

                /tmp/{a,b}/z /tmp/a/z /tmp/b/z

# cd ~
# pwd
/root
# cd ~testuser
testuser]# pwd
/home/testuser

f、bash特性之六:命令的執行狀態結果:

命令的正常輸出結果:命令的返回值;

    通過引用來保存下來或直接調用——”命令引用“

`COMMAND`

$(COMMAND)

# ls -ld `pwd`

命令的執行狀態結果:

成功:0

失?。?-255

# echo "Helllo World"
Helllo World
# echo $?
0
# echoa "Hello World"
-bash: echoa: command not found
# echo $?
127

        bash用一個特殊變量來保存最一次執行的命令的狀態結果:

$?

bash中的引用:

'':強引用

"":弱引用

“:命令引用

# echo '$PATH'
$PATH
# echo "$PATH"
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
# echo `pwd`
/home/testuser

g、bash的特性之七:glob

    glob:文件名通配;快速引用多個文件;文件名整體匹配度檢測;    

    元字符:基于元字符可編寫匹配模式(pattern);

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

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

p*:pa, p

?:匹配任意單個字符;

            p?, p?a, p??

    p??: pa, pad, 

[ ]:匹配指定集合內的任意單個字符;

         [a-z], [A-Z]:不區分字符大小寫;

[0-9]

        [a-z0-9]

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

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

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

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

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

    [[:space:]]:空白字符;

    [[:punct:]]:標點符號;

    [^ ]:匹配指定集合外的任意單個字符;

[^[:alpha:]]

    測試:

     1、顯示/etc目錄下,以非字母開頭,后面跟了一個字母及其它任意長度任意字符的文件或目錄; 

    ls  -d  /etc/[^[:alpha:]][a-z]*

     2、復制/etc目錄下,所以n開頭,以非數字結尾的文件或目錄至/tmp/etc目錄下;

    mkdir /tmp/etc 
    cp  -r  /etc/n*[^0-9]  /tmp/etc/

     3、顯示/usr/share/man目錄下,所有以man開頭,后跟一個數字結尾的文件或目錄;

    ls  -d  /ur/share/man/man[0-9]

     4、復制/etc目錄下,所以p,m,r開頭的,且以.conf結尾的文件或目錄至/tmp/conf.d目錄下;

    mkdir  /tmp/conf.d/
    cp  -r  /etc/[pmr]*.conf   /tmp/conf.d/

h、bash特性之八:變量

程序:指令+數據

數據:文件、變量;

    變量:內存空間,有名稱,名稱即為變量名,對應的內存空間中的數據即為變量的值;

    變量賦值:NAME=VALUE

=:賦值符號;

把VALUE存儲到NAME指向的內存空間中;

編程語言:

強類型:嚴格區分變量中的數據類型;

弱類型:不區分變量中存儲的數據類型,統一為字符型;

bash:統統默認為字符型數據;變量無需事先聲明;

變量為什么有類型?

存儲空間、存儲格式、參與的運算、……

        類型不同決定對數據的處理方式不同

變量命名:只能使用字母、數字和下劃線;而且不能以數字開頭;


變量名:見名知義;不能使用程序保留字,例如if、case、then、fi、esac、for、while、until、break、continue等等;

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

         變量替換:把變量引用符號出現的位置替換為其指向的內存空間中的數據;

bash變量種類:

本地變量:作用域為當前shell進程;不包括其子進程;

環境變量:使用域為當前shell進程及其子進程;

局部變量

    作用域:生效范圍,也即可引用到的范圍;

位置參數變量:

特殊變量

本地變量:

變量賦值:NAME=VALUE

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

""

查看變量:set

撤銷變量:unset NAME

注意:此處非為變量引用,因此不能使用$;

所有的本地變量在shell進程終止時,會被自動撤銷;

   

環境變量:

變量聲明和賦值:

declare -x  NAME[=VALUE]

export  NAME[=VALUE]

引用方式:

${NAME}, $NAME

注意:bash內嵌了許多環境變量,名稱為全大寫字母,例如UID、HOME、PWD、SHELL, PATH, HISTSIZE等等;

環境變量查看:

export, declare  -x

env,  printenv

撤銷環境變量:

unset  NAME

只讀變量:常量

(1) declare  -r  NAME

(2) readonly  NAME

不支持重新賦值,也不支持撤銷操作;

# declare -r username=`whoami`
# echo $username
root
# unset username
-bash: unset: username: cannot unset: readonly variable

i、bash基于特性之九:I/O重定向和管道

程序的數據流有三個:

    輸入數據流: <–,標準輸入(stdin),鍵盤;

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

    錯誤數據流:–>,錯誤輸出(stderr),顯示器;

fd:file descriptor,文件描述符;

stdin: 0

stdout: 1

stderr: 2

IO重定向:

輸出重定向:

重定向程序正常執行的結果

COMMAND >  /PATH/TO/SOMEFILE

覆蓋重定向:覆蓋目標文件中的原有內容;

COMMAND >> /PATH/TO/SOMEFILE

         追加重定向:追加新產生的內容至目標文件尾部;

shell的一個功能開關:

# set -C

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

注意:此時仍然可以使用“>|”至目標文件; 

# set +C

關閉上述特性;

錯誤重定向:

重定向錯誤的執行結果;

COMMAND 2>  /PATH/TO/SOMEFILE

錯誤輸出覆蓋重定向;

COMMAND 2>> /PATH/TO/SOMEFILE

錯誤輸出追加重定向;

合并標準輸出與錯誤輸出流:

(1) &>, &>>

(2) COMMAND > /PATH/TO/SOMEFILE 2>&1

     COMMAND >> /PATH/TO/SOMEFILE 2>&1

特殊輸出目標:/dev/null

位桶:bit bucket

特殊的輸入文件:/dev/zero

輸入重定向:

COMMAND < /PATH/FROM/SOMEFILE

tr命令:把輸出的數據當中的字符,實現對位轉換,即把數據中的存在于字符集中的字符,統統轉換為字符集2中對應的字符;

tr – translate or delete characters

tr [OPTION]… SET1 [SET2]

(1) tr  SET1  SET2 < /PATH/FROM/SOMEFILE

字符轉換

    # cat test 
    Hello World
    # cat test |tr 'a-z' 'A-Z'
    HELLO WORLD

(2) tr  -d  SET1  < /PATH/FROM/SOMEFILE

刪除

# cat test 
    Hello World
    # cat test |tr -d 'ldH'
    eo Wor

COMMAND << :

Here Document

用法:

COMMAND << EOF

COMMAND > /PATH/TO/SOMEFILE << EOF

管道:

COMMAND1 | COMMAND2 | COMMAND3 | …

練習1:把/etc/passwd文件最后三行信息中所有小寫字符改為大寫后輸出;

# tail -3 /etc/passwd|tr 'a-z' 'A-Z'
TEST1:X:5002:5002::/HOME/TEST1:/BIN/BASH
TEST2:X:5003:5003::/HOME/TEST2:/BIN/BASH
TEST3:X:5004:5004::/HOME/TEST3:/BIN/BASH

練習2:取出/etc/fstab的第6行;

# head -6 /etc/fstab |tail -1
# Accessible filesystems, by reference, are maintained under '/dev/disk'

練習3:取出/etc目錄下所有以p開頭的文件或目錄,只顯示前5個;

# ls -d /etc/p*|head -5
/etc/pam.d
/etc/passwd
/etc/passwd-
/etc/pinforc
/etc/pkcs11

tee命令:

tee – read from standard input and write to standard output and files

tee [OPTION]… [FILE]…

    -a:使用追加輸出,而非覆蓋;

        COMMAND | tee /PATH/TO/SOMEFILE

    # cat test|tee /tmp/test.cat
    Hello World
    # cat /tmp/test.cat 
    Hello World

原創文章,作者:Ace,如若轉載,請注明出處:http://www.www58058.com/12259

(1)
AceAce
上一篇 2016-03-09
下一篇 2016-03-09

相關推薦

  • C語言結構體里的成員數組和指針

    單看這文章的標題,你可能會覺得好像沒什么意思。你先別下這個結論,相信這篇文章會對你理解C語言有幫助。這篇文章產生的背景是在微博上,看到@Laruence同學出了一個關于C語言的題,微博鏈接。微博截圖如下。我覺得好多人對這段代碼的理解還不夠深入,所以寫下了這篇文章。 為了方便你把代碼copy過去編譯和調試,我把代碼列在下面: final void&n…

    Linux干貨 2016-05-29
  • 馬哥教育網絡班25期-第2周作業

    一、Linux文件管理類命令: (1)ls             list 用來顯示目錄列表             …

    Linux干貨 2016-12-12
  • 正則表達式詳解

    正則表達式詳解

    2017-09-20
  • 內核編譯流程和自動化安裝

    內核編譯         在特定的情況我們機器上面有些硬件特性需要利用起來,但是我們現成的這個內核沒有開啟這個功能,那就需要重新編譯,把這個功能模塊加進來,或者打到vmlinux中的核心文件里面。比如ntfs功能,默認系統沒有啟用此功能,但是系統是帶這個功能的,編譯的時候時候可以…

    Linux干貨 2016-09-18
  • Bash Shell詳解

    引言:什么是Shell? Linux的命令行接口歸結起來就是各種Shell,那么到底什么是Shell?Shell,譯為外殼,是用戶直接連入計算機所使用的計算機程序,負責解析用戶提供的命令,如詞法分析、語法分析、句法分析。 1.Shell的分類 Linux 的命令 shell 是與操作系統相分離的一層。不同的 shell 環境影響您具備不同的功能,比如可編輯的…

    2017-09-07
  • Trap命令簡介

     Trap命令簡介     一、基本概念  trap是一個shell內建命令,它用來在腳本中指定信號如何處理。比如,按Ctrl+C會使腳本終止執行,實際上系統發送了SIGINT信號給腳本進程,SIGINT信號的默認處理方式就是退出程序。如果要在Ctrl +C不退出程序,那么就得使用trap命令來指定一下SIGINT的處…

    Linux干貨 2015-05-11

評論列表(1條)

  • stanley
    stanley 2016-03-09 09:55

    贊,專業

欧美性久久久久