■ 變量與環境變量
shell環境通常存在很多變量,變量可以通過echo $VAR或${VAR}的方式查看。set命令可以查看當前環境中的所有變量(包括一般的自定義變量和環境變量)
變量的設置通過簡單的賦值命令進行。比如TESTVAR=abc,就是設置了TESTVAR的值為abc(注意等號兩邊都沒有空格,值也不能有空格,有空格就要用引號引起來)。
取消變量的設置可以通過unset命令,如unset TESTVAR。
變量中有一些特殊的變量被稱為環境變量。環境變量的意義在於它可以被子進程繼承,繼而被多個進程共用。由於linux的子進程生成機制是fork-and-exec,所以子進程的環境變量其實是父進程的一個副本,子進程開始運行后就與父進程互相獨立了。通過export命令可以將一般的自定義變量轉化為環境變量用於進程間通訊。env命令可以查看所有環境變量。
■ shell配置文件與環境變量
通過SSH連接centos是一個常見的場景。登錄時,由sshd進程打開一個虛擬終端的子進程,再由虛擬終端進程打開一個bash子進程,這個bash進程就是我們通過這個連接運行所有指令的原點。
順帶一提,打開bash時會有歡迎信息,這些信息配置在/etc/issue(通過終端登錄時)和/etc/motd(通過模擬終端登錄時)。
在正式看bash的配置文件之前,有必要先了解一下login-shell和non-login-shell。從最表象的層面來說,打開bash時需要輸入賬號密碼的shell就是login-shell,反之則不是。前者例子有通過終端登錄linux系統或者SSH遠程登錄模擬終端時,后者的例子有通過圖形化界面打開終端,或者在終端中運行bash再開一個子進程的shell等情況。
在cenots下打開一個bash的shell時,會讀取一些配置文件,加載一些基本的,常用的變量到shell中來。通常會涉及到的配置文件主要有四個:
A. /etc/profile
B. ~/.bash_profile
C. ~/.bashrc
D. /etc/bashrc
通常,打開的是一個login-shell的時候會加載的配置文件是A和B。(說B是只有一個.bash_profile其實也是不太嚴謹的。如果home中.bash_profile不存在則會尋找.bash_login,若它也不存在則尋找.profile。三者按照優先級順序找到一個就加載,其他的就不管了)但是通常,B的具體執行內容中有加載C的步驟,而C的執行內容中又有加載D的步驟,所以一般而言四個都會被加載。由於B和C是每個用戶home目錄下自身的文件,可能有所不同,這點也需要注意。相對的A是所有用戶共用的文件。
若打開的是一個non-login-shell的話,那么只會加載C和D。值得一提的是,D這個文件是redhat系統特有的文件,在其中做出了redhat標志性的一些配置(比如PS1的樣式)。C這個文件在/etc/skel中有備份,如果不小心刪除了可以去那里拿一份回來。
除了上面四個外,還有一些配置文件也和bash的運行息息相關。
~/.bash_history 記錄了當前bash的命令執行歷史,其大小和環境變量HISTSIZE相關。history命令就是讀取這個文件的。歷史命令並不會隨着我們操作同步寫入,我們可以想象是這樣的:登錄時讀取這個文件把HISTSIZE條命令加載到內存中,由於HISTSIZE通常是1000,以1000舉例。然后隨着我們不斷輸入命令,內存中這1000條不斷被更新,總量始終維持在1000。當我們注銷登錄時將這更新后的1000條再次寫入此文件。由於命令記錄和bash進程相關聯,但是.bash_history一個用戶只有一個,所以當同一個用戶用不同bash進程做了不同操作的時候,更新的信息以最后一個注銷的用戶為准。
~/.bash_logout 注銷登錄時留給用戶做一些事的接口。我們可以在里面寫上一些注銷登錄時要機器自動幫你做的事情,比如記錄登出的時間等等。
■ 幾種運行可執行程序(包括運行sh腳本)的區別
對於可執行文件,Linux提供了多種執行方法,按照分類主要有:
1. 通過路徑執行如相對or絕對路徑:./test.sh 、/tmp/test.sh
這種執行方法需要當前用戶對被執行的文件有執行的權限,且如果是一個shell腳本的話在腳本頭應該聲明相應的解釋器如#!/bin/bash。從執行程序的角度而言通過相對或絕對路徑執行沒有區別。
由於一般命令的執行本質也是先找到環境變量PATH中的相關路徑再執行,所以可以視為這一類執行方式。因此,一般命令的執行也都是開了一個子進程的shell來執行的。
2. shell命令執行
通過shell程序的指令執行如: bash test.sh、sh test.sh
通過這種方法執行的程序本身無需有執行權限,只要有讀權限即可。被執行程序作為一個shell程序的參數運行。
3. 以讀取環境變量的方式執行
如: source test.sh 、 . test.sh
這種方式和前兩種最大的區別在於,前兩種都是在現有shell中開啟一個子進程的shell,然后把程序放到子進程的shell環境中執行,執行完成后即關閉子進程shell。而這種方式直接在當前shell環境中執行。所以如果被執行程序中含有對環境變量的增改,且希望保留結果到當前shell環境中的,則需要使用這種方法執行。
