Bash

在登錄時找出 bash 正在執行哪些腳本

  • April 12, 2022

啟動 bash 終端后,我注意到 PATH 變數包含重複的條目。我的終端啟動了一個登錄 shell,所以~/.bash_profile是 sourced ,然後是~/.profileand ~/.bashrc。只有在~/.profile我創建重複的路徑條目。

為了迂腐,這是應該獲取的文件的獲取順序:

Sourced /etc/profile
Sourced /etc/bash.bashrc
Sourced .bash_profile
Sourced .profile
Sourced .bashrc

在有人將此標記為“PATH 變數包含重複項”的重複項之前,請繼續閱讀。

起初我認為這與~/.profile被採購兩次有關,所以每當它被採購時我都會將文件寫入日誌文件,令人驚訝的是它只記錄了一個條目,這告訴我它只被採購了一次。更令人驚訝的是,當我註釋掉 中的條目時~/.profile,這些條目仍然出現在PATH變數中。這使我得出了三個結論,其中一個很快被排除在外:

  1. Bash 忽略有效的 bash 註釋並仍然執行註釋程式碼
  2. 有一個腳本可以讀取~/.profile並忽略任何列印輸出的程式碼(例如日誌文件)
  3. 我的另一個副本~/.profile是在其他地方採購的

第一個,由於一些快速測試,我很快得出結論並非如此。第二個和第三個選項是我需要幫助的地方。

**如何收集終端啟動時執行的腳本列表?**我echo在我檢查過的文件中使用了這些文件,以了解它們是否來自 bash,但我需要找到一個確鑿的方法來跟踪終端準備好開始輸入時的執行情況。

如果以上是不可能的,那麼任何人都可以建議我在哪裡可以查看正在執行的腳本


以後的參考

這是我現在用來添加到我的路徑的腳本:

function add_to_path() {
   for path in ${2//:/ }; do
       if ! [[ "${!1}" =~ "${path%/}" ]]; then # ignore last /
           new_path="$path:${!1#:}"
           export "$1"="${new_path%:}" # remove trailing :
       fi
   done
}

我這樣使用它:

add_to_path 'PATH' "/some/path/bin"

該腳本在添加之前檢查變數中是否已經存在路徑。

對於 zsh 使用者,您可以使用這個等價物:

# prepends the given path(s) to the supplied PATH variable
# ex. add_to_path 'PATH' "$(go env GOPATH)/bin"
function add_to_path() {
   # (P)1 path is expanded from $1
   # ##: Removes leading :
   local -x pth="${(P)1##:}"
   # (s.:.) splits the given variable at :
   for p in ${(s.:.)2}; do
       # %%/ Remove trailing /
       # :P Behaves similar to realpath(3)
       local p="${${p%%/}:P}"
       if [[ ! "$pth" =~ "$p" ]]; then
           pth="$p:$pth"
       fi
   done
   export "$1"="${pth%%:}"
}

編輯 28/8/2018

我發現我可以用這個腳本做的另一件事是修復路徑。所以在我的.bashrc文件的開頭,我做了這樣的事情:

_temp_path="$PATH"
PATH='/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin'
add_to_path 'PATH' "$_temp_path"
unset _temp_path

應該從什麼PATH開始取決於您。先考察PATH再決定。

如果您的系統有,strace那麼您可以列出 shell 打開的文件,例如使用

echo exit | strace bash -li |& grep '^open'

-li表示登錄 shell 互動;僅-i用於互動式非登錄 shell。)

這將顯示 shell 打開或嘗試打開的文件列表。在我的系統上,它們如下:

  1. /etc/profile
  2. /etc/profile.d/*(中的各種腳本/etc/profile.d/
  3. /home/<username>/.bash_profile(這失敗了,我沒有這樣的文件)
  4. /home/<username>/.bash_login(這失敗了,我沒有這樣的文件)
  5. /home/<username>/.profile
  6. /home/<username>/.bashrc
  7. /home/<username>/.bash_history(命令行的歷史;這不是腳本)
  8. /usr/share/bash-completion/bash_completion
  9. /etc/bash_completion.d/*(提供自動完成功能的各種腳本)
  10. /etc/inputrc(定義鍵綁定;這不是腳本)

使用man strace以獲取更多資訊。

引用自:https://unix.stackexchange.com/questions/334382