bash初始化機制

安全劍客發表於2020-06-08
這篇文章主要介紹了詳解bash中的初始化機制,文中透過示例程式碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
Bash初始化檔案
互動式login 

在下列情況下,我們可以獲得一個login shell:

登入系統時獲得的頂層shell,無論是透過本地終端登入,還是透過網路ssh登入。這種情況下獲得的login shell是一個互動式shell。
在終端下使用--login選項呼叫bash,可以獲得一個互動式login shell。
在 中使用--login選項呼叫bash(例如:#!/bin/bash --login)可以得到一個非互動式的login shell。
使用su -切換到指定使用者時,獲得此使用者的login shell。如果不使用-,則獲得non-login shell。
login shell啟動時首先讀取/etc/profile系統全域性配置,然後依次查詢~/.bash_profile、~/.bash_login、~/.profile三個配置檔案,並且讀取首個找到的並且可讀的檔案。

login shell退出時讀取並執行~/.bash_logout中的 。 如果配置檔案存在但不可讀,則會顯示錯誤訊息;如果檔案不存在,bash將自動搜尋下一個檔案。

預設在/etc/profile檔案中會定義PATH、USER、MAIL、HOSTNAME、HISTSIZE等全域性環境變數,還會自動匯入/etc/bash.bashrc檔案(包含系統級shell函式和別名),以及/etc/profile.d路徑下被用於針對特定程式進行初始化的所有*.sh。

互動式non-login shell

非登入shell意味著在啟動時不必透過系統身份驗證。 GUI中使用者開啟的終端預設為非登入shell,可以透過logout 判斷:

# 在Ubuntu GUI桌面開啟一個終端
> logout
bash: logout: not login shell: use `exit'
> bash --login
> logout # 正常登出 什麼也不會輸出

非登入shell在初始化時僅讀取~/.bashrc資原始檔, 而~/.bashrc檔案會自動被~/.bash_profile或~/.profile載入,因此為了保證login shell和互動式non-login shell得到相同的配置,一般將環境變數定義在~/.bashrc檔案中。

> echo "export sflag=\"login shell will see this message\"" >> ~/.profile  
> bash
> echo $sflag 
          # 找不到這個變數 會列印一個空行
> exit
> bash --login 
> echo $sflag 
login shell will see this message 
> logout
非互動式shell

透過bash命令執行 時會以非互動(non-interactively)的方式啟動shell,這保證了在指令碼執行過程中不會被使用者干擾。在非互動式指令碼啟動時,僅會載入BASH_ENV變數指向的檔案。但要注意, 由於PATH變數預設不會被非互動式shell載入,因此變數BASH_ENV的值應該為絕對路徑。

透過特殊變數-可以檢視當前shell的模式:

> echo $-
himBHs # 帶有'i'就是互動式shell

另一個簡單的方式是檢查當前shell中是否存在提示符環境變數PS1.

if [ -z "$PS1" ]; then echo "非互動式";else echo "互動式";fi
特殊情況
相容模式

如果使用命令sh呼叫bash,則為了保證相容性會按照sh的方式對bash進行初始化。作為login shell啟動時,bash依次讀取/etc/profile和~/.profile配置檔案。作為non-login shell啟動時,bash僅會讀取環境變數ENV指向的檔案。

POSIX模式

當透過以下方式啟動bash時:

設定set -o posix 或 export POSIXLY_CORRECT=1
bash --posix

bash會盡可能按照POSIX標準進行初始化,僅會讀取環境變數ENV指向的檔案。

遠端啟動指令碼

使用rshd遠端啟動指令碼時僅會載入 ~/.bashrc檔案,但要注意的是儘量不要使用rlogin, telnet, rsh, rcp等遠端命令,因為這些命令會傳輸未加密的明文資訊。如果有遠端訪問需求儘量使用SSH。

UID與EUID不匹配

在建立程式時會在task_struct中記錄程式執行時所需要的資訊。其中UID(真實使用者ID)用於記錄建立程式的使用者的ID,EUID(有效使用者ID)用於判斷當前程式對檔案的訪問級別,一般情況下UID = EUID。如果可執行檔案的set-user-ID: SUID位有效(例如:-rwsr-xr-x,使用者的x被替換為s),表示當該檔案被執行時,程式具有檔案所有者的許可權而不是執行者的許可權(EUID的值為檔案所有者的ID)。

如果我們給bash可執行檔案設定了set-user-id標誌,那麼由於其預設所有者為root,當其他非root使用者執行bash時,該程式的UID將不等於EUID,這種情況下為了保證安全性,bash在初始化階段不會載入任何檔案。

受限制的shell

透過rbash或bash --restricted或bash -r啟動時會生成功能受限制的shell,具體表現為:

不能使用cd命令並且命令中不能包含/
不能更改SHELL、PATH、ENV和BASH_ENV環境變數
source命令的引數也不能包含帶有/的檔案
hash –p 用於給路徑起別名的命令的引數中也不能包含/
初始化時不會匯入檔案中的函式並且會忽略SHELLOPTS
不能使用重定向
不能使用exec命令
不能使用enable -f/-d增加刪除命令
不能使用command -p指定執行命令需要的路徑
不能主動關閉限制模式
這個功能理論上可以讓使用者在指定的資料夾內執行指定的檔案來完成有限的功能,但是如果環境變數設定不當會導致使用者很輕鬆地就能解除限制:

> rbash
> cd /etc
rbash: cd: restricted
> bash
> cd /etc # 可以成功執行,因為這個時候我們在bash環境中,沒有任何限制

一種有效的做法是給新建的使用者的能執行的命令作出限制,例如我們可以新建一個只能執行ftp命令的ruser:

> useradd -s /bin/rbash ruser # 設定使用者登入時提供的shell
> chown -R root:ruser /home/ruser/.bashrc /home/ruser/.bash_profile
# 設定root為擁有者,ruser組為組擁有者(新建的ruser預設輸入ruser組)
> chmod 640 /home/ruser/.bashrc /home/ruser/.bash_profile
# root可以讀寫,ruser組裡的使用者只讀,其他使用者什麼也不能幹
> mkdir /home/ruser/bin # 儲存使用者的可執行檔案或連結
> echo "export PATH=/home/ruser/bin" >> /home/ruser/.bash_profile
> ln -s /user/bin/ftp /home/ruser/bin/ftp

到此這篇關於詳解bash中的初始化機制的文章就介紹到這了。

原文地址:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559985/viewspace-2696987/,如需轉載,請註明出處,否則將追究法律責任。

相關文章