Bash

將別名轉發給子程序

  • June 1, 2017

/etc/zprofile我有一些在(或/etc/profile用於 bash)中定義的別名。也在$PATH那裡被操縱。

我想從一個避免$PATH操作的 shell 啟動一個互動式 shell。我通過使用-f選項啟動它來做到這一點。然而,在父 shell 中定義的別名很有用,我想將它們轉發給子程序。

將由 once 定義的別名複製並粘貼/etc/zprofile到文本文件中,並在每次我啟動另一個 shell 時獲取它並不是我想要的,因為定義/etc/zprofile得到維護並且可能會隨著時間而改變。

您對如何將別名轉發到第二個 shell 有什麼建議嗎?

(我的主要興趣是zsh解決方案,但我bash也對解決方案感到好奇)

這就是我的情況

# log in with ssh
shell1 > echo "here aliases are the way I want them to be"
shell1 > VARIABLE1=value1 VARIABLE2=value2 PATH=some_paths zsh
shell2 > echo "/etc/zprofile prepended something to PATH, which I don't like"
shell2 > echo "aliases are good"
shell2 > exit
shell1 > VARIABLE1=value1 VARIABLE2=value2 PATH=some_paths zsh -f
shell2 > echo "/etc/zprofile did not prepend something to PATH. This is good!"
shell2 > echo "but all aliases from shell 1 are \"forgotten\""
shell2 > exit

繼續提供資訊;裡面的東西/etc比我最初想像的要復雜得多: /etc/zprofile包含以下內容,我追查到這些內容定義了我的別名和$PATH

_src_etc_profile()
{
   #  Make /etc/profile happier, and have possible ~/.zshenv options like
   # NOMATCH ignored.
   #
   emulate -L ksh

   # source profile
   if [ -f /etc/profile ]; then
       source /etc/profile
   fi
}
_src_etc_profile

unset -f _src_etc_profile

但我錯過了/etc/zshrc包含

_src_etc_profile_d()
{
   #  Make the *.sh things happier, and have possible ~/.zshenv options like
   # NOMATCH ignored.
   emulate -L ksh


   # from bashrc, with zsh fixes
   if [[ ! -o login ]]; then # We're not a login shell
       for i in /etc/profile.d/*.sh; do
       if [ -r "$i" ]; then
           . $i
       fi
       done
       unset i
   fi
}
_src_etc_profile_d

unset -f _src_etc_profile_d

所以它不僅zprofile是通過/etc/profile.d,而且zshrc。然後其中一個文件/etc/profile.d(我添加了關於它如何進行的評論)

if [ -n "$SHLVL" ]; then
   if [ $SHLVL = 1 ]; then
           source /some/group/path/profile
           # calls "source /some/group/path/env"
           # -> see else branch
   else
           source /some/group/path/env
           # calls "source /some/group/path/${SHELL}rc"
           # which then calls
           # "source /my/group/path/group_zshrc"
   fi
else
   echo 'No $SHLVL available, assuming login shell.'
   source /some/group/path/profile
fi

並最終/my/group/path/group_zshrc呼叫一個 python 程序,該程序編寫一個臨時文件,其中定義/操作別名和環境變數,然後最終獲取該文件。

您不應該在/etc/zprofileor中定義別名~/.zprofile。這些文件僅在登錄 shell 中載入(“shell”當然是指 zsh)。定義別名的正確位置是/etc/zshrcor ~/.zshrc,它被所有互動式 shell 讀取。

要在不載入的情況下執行 zsh /etc/zprofile,只需zsh不帶選項執行即可。該選項-f告訴 zsh 根本不要讀取配置文件,但是由於您想讀取別名定義,所以這不是正確的選項。由於/etc/zprofile僅由登錄 shell 讀取,因此不要傳遞-l選項(並且不要設置以破折號開頭的第零個參數)。

Zsh 沒有選項或環境變數可以在啟動時讀取一個額外的文件。如果你想為此做準備,你可以添加eval $ZSH_EXTRA_STARTUP_CODE到你的.zshrc.

您可以設置ZDOTDIR環境變數以使其從不同的目錄讀取所有使用者配置文件,例如ZDOTDIR=/tmp/foo zshreads /etc/zshenv、和. 因此,要將別名從目前實例導出到子實例,您可以執行類似/tmp/foo/.zshenv``/etc/zshrc``/tmp/foo/zshrc

tmp=$(mktemp -d)
alias -L >$tmp/.zshenv
echo ". ~/.zshenv; unset ZDOTDIR; rm -r ${(q)tmp}" >>$tmp/.zshenv
zsh

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