linux 基礎(6)簡單認識 bash

2023-02-08 18:00:14

shell 和 bash 是什麼?

shell 是一種應用程式,在這個程式裡輸入文字指令,系統就會做出響應的操作。這個「殼程式」是我們使用系統各種功能的介面,學會了 shell 就是學會操作 linux 系統。檢索/etc/shells,可以看到當前系統的 shell 有哪些。而 bash (Bourne Again SHell)是大部分 linux 的預設 shell 程式,也是最廣泛使用的 shell。

shell, termial, console, tty 之間的區別

在現代計算機語境下 termial, console, tty 是同一個意思即「終端」。終端就是一個與使用者互動的介面,和 shell 相連線。用 Windows 的軟體名字來理解就非常容易。Bash 的 sh 代表 shell,powershell也是一個shell,他們接受輸入,執行操作;而 windows terminal 就是一個終端,他裝著shell程序,接受鍵盤輸入交給shell,輸出操作結果,管理輸入輸出,字型樣式,大小顏色。

bash 的變數功能

bash 語句可以使用和儲存變數,有了這個功能,bash 就不只是互動工具,而擁有程式設計功能。

變數的讀寫

echo可以檢視一個變數,讀變數需要加上$,如果不存在會讀空值而不是報錯。

echo $var
echo ${var} # 都可以

寫變數不需要符號,直接等號賦值,已有的賦新值,沒有的建立。字串可以複用已有變數。

myvar1=hello # 建立變數,注意等號不能有空格,這和大多數語言不一樣
myvar2="world" # 也可以用單雙引號
myvar2="${myvar1} world" # 雙引號會格式化字串,結果 hello world,沒有引號也會格式化
myvar2='${myvar1} world' # 單引號不會格式化字串,結果 ${myvar1} world
myvar2=hello\ world # 反斜槓可以跳脫,表達空格、反斜槓和單雙引號
unset myvar1 # 刪除變數

特殊用法,可以包裹指令,以指令輸出作為值。

a=$(uname -a) #執行 uname -a,輸入賦值給a
a=`uname -a` #反引號也可以

自訂變數和環境變數

環境變數是開啟 shell 時就載入的一些的變數,他們儲存 bash 的個人設定,非常重要。輸入env查詢環境變數。

當前 shell,主機名稱,當前目錄,PATH,語言設定等,都是編寫程式需要用到的重要變數。

環境變數可以傳遞到 bash 啟動的子程式裡,自定變數卻不可以。想要把自訂變數轉化成環境變數,就用 export 指令

export myvar1

declare 詳細設定變數

declare可以詳細的設定變數屬性。

declare -air myvar
-i: 設定數位型別。使用等號賦值一定得到字串變數,比如`a=3`會得到字串`3`,不能進行數學運算。declare可以建立數位型別變數
-r: 設定為唯讀變數
-a: 設定為陣列型別。bash 的陣列型別沒有太多的功能,主要用於迴圈遍歷

bash 的進階操作

alias 別名

alias 可以給一個長命令全一個短名字,方便實用。如alias ls=ls --color=auto就可以讓 ls 執行時實際執行ls --color=auto。alias 的優先順序高,所以ls會取代原來沒有引數的ls。不同的 distribution 內建了一些常用的alias。

alias la=ls -a
alias ll=ls -al
alias vi=vim
alias rm=rm -i
...

歷史命令

按下上箭頭可以呼叫歷史輸入。也可以使用 history 直接檢視命令。

history 3 # 顯示最近 3 條歷史
history -c # 清除歷史
history -w # 立刻將本 shell 歷史寫入.bash_history,預設在 shell 退出的時候會寫入

感嘆號也可以直接用來呼叫歷史

!92 # 執行歷史指令 92 號
!gcc # 執行最近一條以gcc開頭的指令,這個很方便

由於 .bash_history 一般在 shell 退出的時候更新,如果開啟了多個shell,.bash_history 只有最後退出的 shell 記錄。

資料流和重定向

鍵入一條指令,輸出一堆資料,有一些指令還需要輸入,預設輸出都列印在螢幕上,輸入用鍵盤敲。如果我希望從檔案輸入,從檔案輸出,就需要修改輸入輸出的設定;另一方面,有一些輸出是我們想看到的資訊,叫做標準輸出流,還有一類輸出是報錯資訊,叫做標準錯誤流,他們是可以區分開的。

重定向輸出流使用>>>,重定向錯誤流用2>2>>,輸入流也類似,<表示輸入由檔案提供。

ls >lsinfo # 螢幕無輸出,儲存在lsinfo裡,若沒有則建立,有則覆蓋。
ls >>lsinfo # 螢幕無輸出,儲存在lsinfo裡,若沒有則建立,有則追加。
ls /dir 2>lsinfo # 檢視不存在的目錄會報錯,螢幕無輸出,錯誤資訊輸入lsinfo,若存在則螢幕輸出,2>不接收資訊

ls /dir 2>/dev/null >lsinfo # 輸出到lsinfo,若有錯誤資訊,輸出到/dev/null

./a.out <input.txt # input.txt提供a.out的輸入

/dev/null叫做黑洞裝置,可以直接丟棄任何進來的資訊。

如果我需要像預設情況一樣把輸出流和錯誤流重定向到同一個地方,不能使用>file 2>file的形式,這樣會使兩個程式寫同一個檔案。可以使用&>file或者1>file 2>&1

bash 的一些特性

指令搜尋順序

當我們輸入一個指令,他會在哪裡尋找這個指令呢?首先指定路徑的肯定按路徑執行了,沒有路徑的,則是alias > builtin > PATH file。優先尋找alias,然後是shell內建,最後在 PATH 裡從前往後尋找

提示符

echo $PS1,可以檢視他的值,這就是「命令提示字元」,也就是每次輸入命令前面的提示字元。

echo $PS1
\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$

PS1 的內容是一門微語言,裡面的內容經過替換後就是成為了每次回車前的命令提示字元,比如 \u 代表使用者名稱,\h 代表主機名,\t 代表時間等,\e[]則可以設定字元的粗細顏色等。想要自定義漂亮的提示符,就可以去搜尋 PS1 的語法。

開屏資訊

每次開啟終端顯示的資訊在哪裡修改?這個檔案不在變數而在/etc/issue

cat /etc/issue

這些符號和 PS1 一樣可以自訂修改。可以列印日期,時間,系統資訊等。

設定載入檔案

首先我們要明白,shell 分為 login shell 和 non-login shell。login shell 是每個使用者進入系統輸入賬號密碼登陸成功後取得的那個shell,而 non-login shell 則是已經登入後開啟的其他shell。對於圖形化介面,可以把 GUI 也理解為一個 shell,你開機時已經輸入了賬號密碼,所以開啟的 shell 是 non-login shell。

login shell 首先讀取的組態檔是/etc/profile,這裡是所有使用者共有的基本設定,會根據使用者設定PATH、umask,設定命令引數補全等,不推薦修改。然後會讀取個人設定,首先讀取~/.bash_profile,沒有的話再選擇~/.bash_login,還沒有就讀取~/.profile三個按優先順序,只會讀取其中一個。non-login shell 僅讀取另一個檔案~/.bashrc,不會再讀前面的組態檔。

萬用字元

bash 指定目錄和檔名時支援特殊字元的匹配:

萬用字元和其他特殊字元可以用反斜槓還原成普通字元。