Linux上讀取或設(shè)置環(huán)境和shell變量的教程
簡介
當(dāng)通過 shell 會話與服務(wù)器交互時(shí),有許多信息會被 shell 編譯以確定其行為和對資源的訪問。其中一些設(shè)置包含在配置設(shè)置中,而其他一些則由用戶輸入確定。
Shell 跟蹤所有這些設(shè)置和詳細(xì)信息的一種方式是通過它維護(hù)的一個(gè)稱為環(huán)境的區(qū)域。環(huán)境是 shell 每次啟動(dòng)會話時(shí)構(gòu)建的一個(gè)區(qū)域,其中包含定義系統(tǒng)屬性的變量。
在本指南中,我們將討論如何與環(huán)境進(jìn)行交互,并通過配置文件以及交互方式讀取或設(shè)置環(huán)境和 shell 變量。
如果您想要在本地系統(tǒng)或遠(yuǎn)程服務(wù)器上跟隨操作,請打開終端并在那里運(yùn)行本教程中的命令。
環(huán)境和環(huán)境變量的工作原理
每次 shell 會話生成時(shí),都會進(jìn)行一個(gè)過程來收集和編譯應(yīng)該對 shell 進(jìn)程及其子進(jìn)程可用的信息。它從系統(tǒng)的各種不同文件和設(shè)置中獲取這些設(shè)置的數(shù)據(jù)。
環(huán)境提供了一個(gè)介質(zhì),通過它,shell 進(jìn)程可以獲取或設(shè)置設(shè)置,并將這些傳遞給其子進(jìn)程。
環(huán)境被實(shí)現(xiàn)為表示鍵值對的字符串。如果傳遞了多個(gè)值,它們通常由冒號(:)字符分隔。每對通??雌饋硐襁@樣:
KEY=value1:value2:...
如果值包含重要的空格,則使用引號:
KEY="帶有空格的值"
這些情況下的鍵是變量。它們可以是環(huán)境變量或 shell 變量中的一種。
環(huán)境變量是為當(dāng)前 shell 定義的變量,并且會被任何子 shell 或進(jìn)程繼承。環(huán)境變量用于將信息傳遞給從 shell 生成的進(jìn)程。
Shell 變量是僅包含在設(shè)置或定義它們的 shell 中的變量。它們通常用于跟蹤短暫數(shù)據(jù),比如當(dāng)前工作目錄。
按照慣例,這些類型的變量通常使用全大寫字母定義。這有助于用戶在其他上下文中區(qū)分環(huán)境變量。
打印 Shell 和環(huán)境變量
每個(gè) shell 會話都會跟蹤其自己的 shell 和環(huán)境變量。我們可以以幾種不同的方式訪問這些變量。
我們可以使用 env 或 printenv 命令查看所有環(huán)境變量的列表。在默認(rèn)狀態(tài)下,它們應(yīng)該完全相同:
printenv
您的 shell 環(huán)境可能設(shè)置了更多或更少的變量,并且具有不同的值,如下所示:
SHELL=/bin/bash TERM=xterm USER=demouser LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca:... MAIL=/var/mail/demouser PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games PWD=/home/demouser LANG=en_US.UTF-8 SHLVL=1 HOME=/home/demouser LOGNAME=demouser LESSOPEN=| /usr/bin/lesspipe %s LESSCLOSE=/usr/bin/lesspipe %s %s _=/usr/bin/printenv
這在 printenv 和 env 的輸出中是相當(dāng)?shù)湫偷摹_@兩個(gè)命令之間的區(qū)別只在它們更具體的功能上才會顯現(xiàn)。例如,使用 printenv,您可以請求單個(gè)變量的值:
printenv PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
另一方面,env 允許您通過將一組變量定義傳遞給命令來修改程序運(yùn)行的環(huán)境:
env VAR1="value" command_to_run command_options
由于,正如我們上面了解的那樣,子進(jìn)程通常會繼承父進(jìn)程的環(huán)境變量,這使您有機(jī)會覆蓋值或?yàn)樽舆M(jìn)程添加額外的變量。
從我們的 printenv 命令的輸出中可以看出,系統(tǒng)文件和進(jìn)程已經(jīng)設(shè)置了相當(dāng)多的環(huán)境變量,而無需我們的輸入。
這些顯示了環(huán)境變量,但我們?nèi)绾尾榭?shell 變量呢?
set 命令可以用于此目的。如果我們不帶任何額外參數(shù)地輸入 set,我們將得到所有 shell 變量、環(huán)境變量、本地變量和 shell 函數(shù)的列表:
set
BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() . . .
這通常是一個(gè)龐大的列表。您可能希望將其傳輸?shù)揭粋€(gè)分頁程序中,以更輕松地處理輸出的數(shù)量:
set | less
我們收到的額外信息量有點(diǎn)壓倒性。我們可能不需要知道所有定義的 bash 函數(shù),例如。
我們可以通過指定 set 應(yīng)該在 POSIX 模式下運(yùn)行來清理輸出,這樣就不會打印 shell 函數(shù)。我們可以在子 shell 中執(zhí)行此操作,以便不更改當(dāng)前環(huán)境:
(set -o posix; set)
這將列出所有已定義的環(huán)境和 shell 變量。
我們可以嘗試將此輸出與 env 或 printenv 命令的輸出進(jìn)行比較,以嘗試獲取僅 shell 變量的列表,但由于這些命令輸出信息的方式不同,這將是不完美的:
comm -23 <(set -o posix; set | sort) <(env | sort)
由于 set 命令輸出帶引號的值,而 printenv 和 env 命令不引用字符串的值,這可能仍然會包括一些環(huán)境變量。
這仍然應(yīng)該給您一個(gè)關(guān)于在您的會話中設(shè)置的環(huán)境和 shell 變量的很好的概念。
這些變量用于各種事情。它們提供了一種在進(jìn)程之間設(shè)置持久值的替代方式,而無需將更改寫入文件。
常見的環(huán)境變量和 Shell 變量
一些環(huán)境變量和 Shell 變量非常有用,經(jīng)常被引
SHELL: 描述將解釋你輸入的任何命令的 shell。在大多數(shù)情況下,默認(rèn)情況下將是 bash,但如果你喜歡其他選項(xiàng),也可以設(shè)置其他值。TERM: 運(yùn)行 shell 時(shí)指定要模擬的終端類型。不同的硬件終端可以模擬不同的操作要求。通常情況下,你不需要擔(dān)心這個(gè)。USER: 當(dāng)前登錄的用戶。PWD: 當(dāng)前工作目錄。OLDPWD: 上一個(gè)工作目錄。這由 shell 保留,以便通過運(yùn)行cd -切換回先前的目錄。LS_COLORS: 定義用于可選地向ls命令添加彩色輸出的顏色代碼。這用于區(qū)分不同的文件類型,并在一瞥中向用戶提供更多信息。MAIL: 當(dāng)前用戶郵箱的路徑。PATH: 系統(tǒng)在查找命令時(shí)將檢查的目錄列表。當(dāng)用戶輸入命令時(shí),系統(tǒng)將按照這個(gè)順序檢查可執(zhí)行文件所在的目錄。LANG: 當(dāng)前語言和本地化設(shè)置,包括字符編碼。HOME: 當(dāng)前用戶的主目錄。_: 最近執(zhí)行的命令。
除了這些環(huán)境變量之外,你經(jīng)常會看到一些 shell 變量,例如:
BASHOPTS: 在執(zhí)行 bash 時(shí)使用的選項(xiàng)列表。這對于查找 shell 環(huán)境是否按照你想要的方式運(yùn)行很有用。BASH_VERSION: 以人類可讀的形式顯示的 bash 版本。BASH_VERSINFO: 以機(jī)器可讀的輸出顯示的 bash 版本。COLUMNS: 在屏幕上繪制輸出時(shí)使用的列數(shù)。DIRSTACK: 使用pushd和popd命令可用的目錄堆棧。HISTFILESIZE: 存儲到文件中的命令歷史記錄行數(shù)。HISTSIZE: 內(nèi)存中允許的命令歷史記錄行數(shù)。HOSTNAME: 此時(shí)計(jì)算機(jī)的主機(jī)名。IFS: 用于在命令行上分隔輸入的內(nèi)部字段分隔符。默認(rèn)情況下是空格。PS1: 主要命令提示符定義。這用于定義你啟動(dòng) shell 會話時(shí)提示的外觀。PS2用于聲明當(dāng)命令跨多行時(shí)的次要提示。SHELLOPTS: 可以使用set選項(xiàng)設(shè)置的 shell 選項(xiàng)。UID: 當(dāng)前用戶的 UID。
設(shè)置 Shell 和環(huán)境變量
用。以下是一些你經(jīng)常會遇到的常見環(huán)境變量:
為了更好地理解 shell 和環(huán)境變量之間的區(qū)別,并介紹設(shè)置這些變量的語法,我們將進(jìn)行一個(gè)小型演示。
創(chuàng)建 Shell 變量
我們將從在當(dāng)前會話中定義一個(gè) shell 變量開始。這很容易實(shí)現(xiàn);我們只需要指定一個(gè)名稱和一個(gè)值。我們將遵循變量名稱全大寫的約定,并將其設(shè)置為一個(gè)簡單的字符串。
TEST_VAR='Hello World!'
在這里,我們使用引號,因?yàn)樽兞康闹蛋崭瘛4送?,我們使用單引號,因?yàn)楦袊@號是 bash shell 中的特殊字符,如果不轉(zhuǎn)義或放入單引號中,它通常會擴(kuò)展為 bash 歷史記錄。
現(xiàn)在我們有了一個(gè) shell 變量。這個(gè)變量在當(dāng)前會話中可用,但不會傳遞給子進(jìn)程。
我們可以通過在 set 輸出中查找我們的新變量來驗(yàn)證這一點(diǎn):
set | grep TEST_VAR
TEST_VAR='Hello World!'
我們可以通過嘗試使用 printenv 來驗(yàn)證這不是一個(gè)環(huán)境變量:
printenv | grep TEST_VAR
不應(yīng)返回任何輸出。
讓我們利用這個(gè)機(jī)會演示訪問任何 shell 或環(huán)境變量的值的一種方法。
echo $TEST_VAR
Hello World!
如你所見,通過在變量前加上 $ 符號來引用變量的值。shell 會在遇到這個(gè)符號時(shí)替換變量的值。
現(xiàn)在我們有了一個(gè) shell 變量。它不應(yīng)該傳遞給任何子進(jìn)程。我們可以從當(dāng)前 shell 中生成一個(gè)新的 bash shell來演示:
bash echo $TEST_VAR
如果我們輸入 bash 生成一個(gè)子 shell,然后嘗試訪問變量的內(nèi)容,將不會返回任何內(nèi)容。這是我們預(yù)期的結(jié)果。
通過輸入 exit 返回到我們的原始 shell:
exit
創(chuàng)建環(huán)境變量
現(xiàn)在,讓我們將我們的 shell 變量轉(zhuǎn)換為環(huán)境變量。我們可以通過導(dǎo)出變量來實(shí)現(xiàn)這一點(diǎn)。相應(yīng)的命令是:
export TEST_VAR
這將把我們的變量變成環(huán)境變量。我們可以通過再次檢查我們的環(huán)境列表來驗(yàn)證這一點(diǎn):
printenv | grep TEST_VAR
TEST_VAR=Hello World!
這次,我們的變量顯示出來了。讓我們再次嘗試在我們的子 shell 中進(jìn)行實(shí)驗(yàn):
bash echo $TEST_VAR
Hello World!
太棒了!我們的子 shell 已經(jīng)接收到了由其父級設(shè)置的變量。在我們退出這個(gè)子 shell 之前,讓我們嘗試導(dǎo)出另一個(gè)變量。我們可以像這樣一步設(shè)置環(huán)境變量:
export NEW_VAR="Testing export"
測試它是否作為環(huán)境變量導(dǎo)出:
printenv | grep NEW_VAR
NEW_VAR=Testing export
現(xiàn)在,讓我們退出回到我們的原始 shell:
exit
讓我們看看我們的新變量是否可用:
echo $NEW_VAR
沒有返回任何內(nèi)容。
這是因?yàn)榄h(huán)境變量只傳遞給子進(jìn)程。沒有內(nèi)置的方法可以設(shè)置父 shell 的環(huán)境變量。在大多數(shù)情況下,這是很好的,可以防止程序影響調(diào)用它們的操作環(huán)境。
NEW_VAR 變量在我們的子 shell 中被設(shè)置為環(huán)境變量。這個(gè)變量將對其自身和任何其子 shell 和進(jìn)程可用。當(dāng)我們退出回到我們的主 shell 時(shí),該環(huán)境被銷毀。
降級和取消變量
我們?nèi)匀粚⑽覀兊?TEST_VAR 變量定義為環(huán)境變量。我們可以通過輸入以下命令將其改回為 shell 變量:
export -n TEST_VAR
它不再是環(huán)境變量:
printenv | grep TEST_VAR
但它仍然是一個(gè) shell 變量:
set | grep TEST_VAR
TEST_VAR='Hello World!'
如果我們想完全取消一個(gè)變量,無論是 shell 還是環(huán)境變量,我們可以使用 unset 命令:
unset TEST_VAR
我們可以驗(yàn)證它是否已經(jīng)取消:
echo $TEST_VAR
沒有返回任何內(nèi)容,因?yàn)樵撟兞恳驯蝗∠?/p>
在登錄時(shí)設(shè)置環(huán)境變量
我們已經(jīng)提到許多程序使用環(huán)境變量來決定如何操作的具體細(xì)節(jié)。我們不想每次啟動(dòng)新的 shell 會話時(shí)都要設(shè)置重要的變量,而且我們已經(jīng)看到許多變量在登錄時(shí)已經(jīng)設(shè)置了,那么我們?nèi)绾巫詣?dòng)創(chuàng)建和定義變量呢?
實(shí)際上,這是一個(gè)比最初看起來更復(fù)雜的問題,因?yàn)?bash shell 根據(jù)啟動(dòng)方式讀取許多配置文件。
登錄、非登錄、交互和非交互式 shell 會話之間的區(qū)別
bash shell 根據(jù)會話的啟動(dòng)方式讀取不同的配置文件。
不同會話之間的一個(gè)區(qū)別是 shell 是否作為登錄或非登錄會話生成。
登錄 shell 是通過對用戶進(jìn)行身份驗(yàn)證開始的 shell 會話。如果您通過終端會話或 SSH 進(jìn)行登錄并進(jìn)行身份驗(yàn)證,您的 shell 會話將被設(shè)置為登錄 shell。
如果您在已經(jīng)經(jīng)過身份驗(yàn)證的會話中啟動(dòng)一個(gè)新的 shell 會話,就像我們通過終端調(diào)用 bash 命令一樣,將啟動(dòng)一個(gè)非登錄 shell 會話。在啟動(dòng)子 shell 時(shí),您沒有被要求輸入身份驗(yàn)證詳細(xì)信息。
另一個(gè)可以區(qū)分的是 shell 會話是否是交互式的,還是非交互式的。
交互式 shell 會話是連接到終端的 shell 會話。非交互式 shell 會話是不連接到終端會話的。
因此,每個(gè) shell 會話都被歸類為登錄或非登錄,交互式或非交互式。
作為登錄會話啟動(dòng)的會話將首先從 /etc/profile 文件讀取配置詳細(xì)信息。然后,它將查找用戶主目錄中的第一個(gè)登錄 shell 配置文件以獲取用戶特定的配置詳細(xì)信息。
它會讀取 ~/.bash_profile、~/.bash_login 和 ~/.profile 中找到的第一個(gè)文件,并且不會再讀取任何其他文件。
相反,作為非登錄 shell 定義的會話將從 /etc/bash.bashrc 開始讀取,然后讀取用戶特定的 ~/.bashrc 文件來構(gòu)建其環(huán)境。
非交互式 shell 會讀取名為 BASH_ENV 的環(huán)境變量,并讀取指定的文件來定義新的環(huán)境。
實(shí)現(xiàn)環(huán)境變量
正如你所看到的,通常我們需要查看各種不同的文件來設(shè)置我們的環(huán)境變量。
這提供了很大的靈活性,可以幫助在特定情況下設(shè)置登錄 shell 中的某些設(shè)置,以及在非登錄 shell 中設(shè)置其他設(shè)置。然而,大多數(shù)情況下,我們希望在這兩種情況下設(shè)置相同的設(shè)置。
幸運(yùn)的是,大多數(shù) Linux 發(fā)行版都配置了登錄配置文件來源自非登錄配置文件。這意味著你可以在非登錄配置文件中定義你希望在兩種情況下都存在的環(huán)境變量。然后這些變量將在兩種情況下都被讀取。
通常我們會設(shè)置特定于用戶的環(huán)境變量,并且通常希望我們的設(shè)置在登錄和非登錄 shell 中都可用。這意味著定義這些變量的地方是在 ~/.bashrc 文件中。
現(xiàn)在打開這個(gè)文件:
nano ~/.bashrc
這很可能已經(jīng)包含了相當(dāng)多的數(shù)據(jù)。這里大多數(shù)的定義是用于設(shè)置 bash 選項(xiàng),與環(huán)境變量無關(guān)。你可以像在命令行中一樣設(shè)置環(huán)境變量:
export VARNAME=value
任何新的環(huán)境變量都可以添加到 ~/.bashrc 文件的任何位置,只要它們不被放在另一個(gè)命令或 for 循環(huán)的中間。然后保存并關(guān)閉文件。下次啟動(dòng) shell 會話時(shí),你的環(huán)境變量聲明將被讀取并傳遞給 shell 環(huán)境。你可以通過輸入以下命令強(qiáng)制當(dāng)前會話立即讀取文件:
source ~/.bashrc
如果你需要設(shè)置系統(tǒng)范圍的變量,你可能需要考慮將它們添加到 /etc/profile、/etc/bash.bashrc 或 /etc/environment 中。
結(jié)論
環(huán)境變量和 shell 變量始終存在于你的 shell 會話中,非常有用。它們是父進(jìn)程為其子進(jìn)程設(shè)置配置細(xì)節(jié)的一種有趣方式,也是在文件之外設(shè)置選項(xiàng)的一種方式。
在特定情況下,這有很多優(yōu)勢。例如,一些部署機(jī)制依賴環(huán)境變量來配置認(rèn)證信息。這很有用,因?yàn)樗恍枰獙⑦@些信息保存在可能被外部人員看到的文件中。
還有許多其他更普通但更常見的情況,你將需要讀取或更改系統(tǒng)的環(huán)境。這些工具和技術(shù)應(yīng)該為你提供了一個(gè)良好的基礎(chǔ),以便進(jìn)行這些更改并正確使用它們。
以上就是Linux上讀取或設(shè)置環(huán)境和shell變量的教程的詳細(xì)內(nèi)容,更多關(guān)于Linux設(shè)置環(huán)境和shell變量的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
linux下怎樣用命令啟動(dòng)docker服務(wù)
這篇文章主要介紹了linux下怎樣用命令啟動(dòng)docker服務(wù)問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
阿里云linux服務(wù)器上使用iptables設(shè)置安全策略的方法
這篇文章主要介紹了阿里云linux服務(wù)器上使用iptables設(shè)置安全策略的方法,需要的朋友可以參考下2016-10-10
詳解ubuntu20.04下CLion2020.1.3安裝配置ROS過程說明
這篇文章主要介紹了ubuntu20.04下CLion2020.1.3安裝配置ROS過程說明,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
phpStudy環(huán)境下安裝配置SSL證書實(shí)現(xiàn)加密訪問(Https)
phpStudy環(huán)境下安裝配置SSL證書,本文主要介紹了phpStudy環(huán)境下安裝配置SSL證書實(shí)現(xiàn)加密訪問,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09

