SHELL 深入理解指令碼的環境變數訪問過程

2021-09-14 05:04:28 字數 4839 閱讀 3334

樓主最近在研究jenkinsgitlab-ci, 以及node環境下js指令碼執行.發現環境變數的配置有時候讀取失敗. 同時在切換角色的時候, 如su - usersu user實際上的讀取環境配置是不一樣的. 大致介紹這裡, 接下來進入正題。

引用wiki百科的介紹

終端是一台電腦或者計算機系統,用來讓使用者輸入資料,及顯示其計算結果的機器
偽終端

一般情況下, 我們採用ssh命令去連線遠端伺服器. 此時在伺服器會建立乙個偽終端程序. 使用tty返回/dev/pts/n內容

虛擬終端

如果直接在機器上啟動終端, 那麼則使用的是tty[1-n]虛擬控制台終端. mac下的虛擬控制台終端為/dev/ttys[001-nnn]

login shellno-login shellinteractive shellnon-interactive shell

login shell

常見的進入login shell的幾種方式:

1. 主機進入控制台終端

2. ssh遠端登入進入偽終端

3. su - 使用者名稱

login shell進入後會依次讀取以下幾類配置檔案

/etc/profile~/.bash_profile,~/.bash_login,~/.profile(只讀取其中乙個配置檔案, 匹配其中乙個檔案後不再讀取其它檔案, 讀取順序與顯示順序一致)

non-login shell

non-login shell, 顧名思義, 不是通過登入的方式進入的shell環境, 如直接使用/usr/bin/bash,/usr/bin/sh之類進入的shell環境.

進入non-login shell的幾種方式

當前login shell情況下, 使用bash進入子shell程序

x window登入linux後,再以x的圖形介面啟動終端機

non-login shell進入後會依次讀取配置檔案~/.bashrc(通常.bashrc指令碼內又會讀取/etc/bashrc)

interactive shell

在控制台終端或者偽終端裡,shell等待你的輸入,並且立即執行你提交的命令。這種模式被稱作互動式是因為shell與使用者進行互動.

non-interactive shell

使用shell執行指令碼檔案, 或者通過管道的形式將輸出轉向shell程式。 那麼指令碼執行的環境屬於非互動性shell.

q&a如何判斷當前 shell 為login shell還是non-login shell?

[主機名]$ echo $0 # 返回 `-bash`

[主機名]$ /usr/bin/bash # 進入non-login shell

[主機名]$ echo $0 # 返回 `bash`

echo $0如果為-bash, 即第乙個符號為-, 則表示該shell為login shell. 如果開頭沒有-則代表為non-login shell

如何在login shell也能讀取到.bashrc的配置?

.bash_profile加入下面這段內容, 表示每次進入後都會執行

if [ -f ~/.bashrc ]; then

. ~/.bashrc

fi

如何判斷當前 shell 為interactive shell還是non-interactive shell?

[主機名]$ echo $- # 返回 `himbh`

[主機名]$ echo 'echo $-' | bash # 返回 `hb`

在shell環境下執行echo $-, 如果返回的為himbh則為interactive shell, 如果返回的為hb, 則為interactive shell

四種組合情況及案例介紹

login shell&non-interactive shell

non-login shell&interactive shell

non-login shell&non-interactive shell

定義在~/.bash_profile

export path=$path:$home/.local/bin:$home/bin
定義在~/.bashrc

export path=$path:/usr/local/node-v6.9.5/bin
在互動型shell, 使用 變數名=變數值 (影響該shell的環境變數)

$ > env=test

$ > echo $env

在互動型shell, 使用 變數名=變數值 ./指令碼檔案 (只影響執行指令碼shell的環境變數, 相當於設定變數而非環境變數)

test.js

console.log(process.env.node_env)
互動型shell環境

node_env=test node test.js # echo test

echo $node_env # echo empty

在互動型shell, 使用 export 變數名=變數值 && ./指令碼檔案 (影響執行shell的環境變數)

test.js

console.log(process.env.node_env)
互動型shell環境

$ > export node_env=test && ./test.js # echo test

$ > echo $node_env # echo test

在執行指令碼內, 使用 export 變數名=變數值, 只影響shell指令碼內執行的程式的環境變數.

test.sh

export node_env='test'

node ./test.js

test.js

console.log(process.env.node_env);
互動型shell環境

./test.sh  # echo test

echo $node_env # echo empty

node,npm為例, 執行目錄/usr/local/node/bin加入了$path中,sudo npm執行卻失敗了

$ sudo npm install lodash # 執行失敗

$ sudo echo $path

/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/usr/local/php/bin:/usr/local/node/bin

$ sudo which npm

which: no npm in (/sbin:/bin:/usr/sbin:/usr/bin)

原因在於 sudo指令為了安全起見,限制了path的目錄, 解決辦法:

因為經常和伺服器打交道, 時常會使用一些指令碼, 而環境變數則是其中非常重要的一節內容.

其實不止以上這些定義環境變數的方式, 在nginx.conf的配置中也可以定義fastcgi_param 環境變數傳遞給 php-fpm 程序, php-fpm.conf也可以定義環境變數傳遞給php-fpm程序. 如果還有相關的知識, 也會繼續做總結.

crontab啟動shell指令碼的環境變數問題

問題描述 crontab中啟動的shell指令碼不能正 常執行,但是使用手動執行沒有問題,在 home pr ofile中設定了指令碼所需要的環境變數。cron命令的預設shell是 bin sh,如果要在cron啟動的指令碼中使用 ksh,就必須在指令碼中的第一行新增 bin sh 的宣告。如果c...

深入理解CSS3裡的transform變換

transform是css3中實現各種炫酷效果的樣式屬性,基礎的轉換函式有縮放scale 平移translate transform對元素在文件流中的盒模型的影響就相當於position relative,不會改變盒模型,包括大小和位置。比如 動畫 右控制箭頭左右擺動 keyframes swing...

深入理解Shell輸出顏色與控制

前言 大家都知道使用ls命令列出檔案列表時,不同的檔案型別會用不同的程式設計客棧顏色顯示。那麼如何實現這樣帶顏色的文字輸出呢?答案並不複雜,不管是用shell還是c語言。一 shell下的實現方法 先來講在shell下,如何實現。用echo命令就可以實現,參看以下例子 echo e 33 32mhe...