Bash 的若干基本問題

Bash Linux 腳本語言 軟件 科技優家 2017-05-09

這裡介紹一些bash啟動前、後的問題,以及一些使用bash需要注意的基本問題。

1、Bash的介紹

Bash是一種Shell程序,它是一般的Linux系統中的默認的Shell程序,一般情況下Bash指的是/bin/bash這個軟件。

一個Linux系統中有多少個可用的Shell程序,可以從/etc/shells文件中查出來。

當前登錄用戶的默認Shell是哪一個,可以從/etc/passwd文件中與此用戶對應的那一行最後一個字段看出來。或者也可以通過echo $SHELL來查看。

2、內部命令與外部命令

Bash中可用的命令分為兩類,分別是:內部命令和外部命令。內部命令是Bash的一部分,而外部命令都是一個一個獨立於Bash的軟件。

在bash的用戶提示符下,可以輸入內部命令和外部命令,然後bash會分析命令,之後執行命令。bash執行內部命令不會產生新的進程,而在執行外部命令的時候,bash會用fork函數生成一個新的進程,然後用exec函數來加載這個外部命令的程序來執行這個外部命令。

怎麼來區分一個命令是內部命令還是外部命令呢?用type命令來區分。type本身是一個內部命令,type commandName可以知道commandName這條命令的是內部命令還是外部命令。

3、環境變量與用戶自定義變量

環境變量是對所有的進程(包括bash的進程和非bash的進程)都可見的變量,一般用大寫字母的組合作為變量名,所以也稱為全局變量。

名詞解析:臨時環境變量和永久環境變量。其實全局變量都是通過export導出的變量。

臨時全局變量是在bash的命令提示符下或者bash scripts下用export導出的變量,這些變量在機器重啟之後會消失,除非再次執行export命令或者再次執行相應的scripts。

永久環境變量是寫在配置文件中的,這些配置文件在每次重啟機器甚至重開一個bash的時候都會被再執行一次,所以這些文件中的全局變量一直存在,不會因為重啟機器而消失,看上去好像是永久的,其實是每次都重新export了。

用戶自定義變量是對單個Bash可見的變量,其他任何從擁有這個變量的Bash生成的子進程(包括子bash進程和其他的子進程)都看不到這個變量,所以也稱為局部變量。

環境變量和用戶自定義變量的主要區別是:環境變量會被bash啟動的子進程繼承,而自定義變量不會被bash的子進程繼承。

系統中的環境變量,可以用env命令和export命令來查看。在bash的命令提示符下直接輸入env或者export都將列出系統的所有環境變量。

在bash下輸入set命令既可以看到系統的環境變量,也可以看到此bash所擁有的用戶自定義變量,另外列出的變量中還有一些是與bash的操作接口有關的變量。

4、shell scripts的執行方式

bash腳本程序的執行方式,一種是由本bash來分析scripts,然後執行,第二種是另外啟動一個新的bash進程,由新bash進程來分析和執行scripts。

在本bash中分析和執行scripts的做法,用source命令或者點命令來執行:

[zzl@myhost Scripts]$ source test.sh

[zzl@myhost Scripts]$ . test.sh

另起一個bash進程執行,有兩種方式:

[zzl@myhost Scripts]$ bash test.sh

[zzl@myhost Scripts]$ chmod a+x test.sh (這裡需要在test.sh的開頭要用shebang註明將要使用的shell)

[zzl@myhost Scripts]$ ./test.sh

5、Bash下的單個命令的交互執行過程

用戶在bash的命令提示符下輸入一條命令,bash就解釋執行一條,這種方式成為交互式。

交互式的情況下內部命令的執行:用戶輸入了一條內部命令之後,bash分析命令,直接執行。執行內部命令相當於執行bash的一個函數。

交互式的情況下外部命令的執行:用戶在命令行輸入一條命令後,bash會分析這條命令的合法性,之後會fork出一個新進程,並在新進程中exec這條命令的程序。

6、shell scripts的執行過程

bash中scripts的執行過程與執行方式有關係。當用source或者點命令時是由本bash來執行此scripts的,如果是由bash命令或者直接執行腳本,則是另起一個子bash進程來執行scripts的。

那麼一個bash進程或者bash的子進程又是怎麼執行scripts的呢?

[zzl@myhost Scripts]$ source test.sh

這條命令執行後,當前bash會把test.sh當成一個命令行參數讀入,之後從test.sh中讀取一條、分析一條、執行一條,直至全部執行完畢。

[zzl@myhost Scripts]$ bash test.sh

這條命令執行後,當前bash會另外啟動一個子bash進程,子bash把test.sh當成自己的命令行參數讀入。

之後,子bash會從test.sh中讀取一條,分析一條,執行一條。在這個過程中,如果讀取的是內部命令,直接調用自己的對應函數;如果讀取的是一個外部命令,那麼它會fork一個子進程,然後在子進程中exec這個外部命令的程序,執行它。

直到test.sh中所有的命令都執行完了,子bash會結束,返回到當前bash中。

7、Bash的操作環境

登錄系統前的歡迎信息放在/etc/issue中、登錄後想要顯示的信息放在/etc/motd中。

login shell:在進入bash的時候,經過了完整的輸入用戶名和密碼的登錄過程,之後才進入bash,那麼這個bash叫做login shell。

non login shell:在進入bash的時候,不需要經過登錄過程,那麼這個bash就是non login bash。比如,在X Window下,打開一個terminal終端,之後進入的bash,就是non login shell;又不如,在命令提示符下輸入bash,之後進入的bash也是non login shell。

login shell在進入之前要讀取/etc/profile、~/.bash_profile或~/.bash_login或~/.profile等配置文件,而在~/.bash_profile中又會執行~/.bashrc文件。

non login shell在進入之前只會讀取~/.bashrc文件。

login shell在註銷退出的時候會讀取~/.bash_logout配置文件的內容,而non login shell則不會讀取。

~/.bash_history文件記錄了上次及以前的會話中login shell使用過的命令。

以上基本問題搞清楚了,bash的使用過程中很多問題就清楚了。餘下的問題是Bash內的問題,就是怎麼學習bash腳本編程的問題和各個命令的用法問題了。

相關推薦

推薦中...