Bash

/usr/bin/env -i /bin/bash –norc –noprofile 之後 PATH 不為空

  • October 14, 2020

我無法理解以下結果:

/tmp/% /usr/bin/env -i /bin/bash --norc --noprofile
bash-5.0$ echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:.

我預計PATH會是空的。

實際上,在某種程度上它是:

bash-5.0$ /usr/bin/printenv
PWD=/tmp
SHLVL=1
_=/usr/bin/printenv

所以環境PATH中沒有,但是仍然定義了一個非空變數,並且可以被shell用來解析命令:PATH

bash-5.0$ which ls
/bin/ls

我意識到我可以強迫/usr/bin/env這樣一個空PATH

/tmp/% /usr/bin/env -i PATH= /bin/bash --norc --noprofile
bash-5.0$ /usr/bin/printenv
PWD=/tmp
SHLVL=1
PATH=
_=/usr/bin/printenv
bash-5.0$ echo $PATH

bash-5.0$ 

這種方法有兩個問題:1)PATH在輸出中顯示/usr/bin/printenv;如果它完全消失了,我會更喜歡它;2) 上述情況並非獨有PATH;在/usr/bin/env -i生成的 shell 會話中仍然定義了很多變數之後。

問:/bin/bash用盡可能少的變數定義(無論是否在環境中)啟動互動式會話的最簡單方法是什麼?1

(雖然我已經用 來表達這個問題bash,但我也對有關 的任何相關資訊感興趣zsh。)


1我知道如果某些變數未定義,許多程序將無法正常執行或根本無法執行。我不打算將這種最小的 shell 會話用於除故障排除、診斷等之外的任何事情。

是的,當它們在啟動時收到的環境中未提供時,兩者bashzsh(並且dash至少)都設置為預設值。mksh``fish``$PATH

仍然不需要在預設搜尋路徑中查找命令的 POSIX shell。

bash和(以及在後者中自動載入或不自動載入的一些模組)都zsh設置了一些內部變數,其中一些被導出到環境中(PATH儘管在bashand的情況下不是zsh),其中一些是只讀的。

env -i zsh -f或者env -i bash --norc會在一個空的環境中執行 shell。

要取消設置非只讀的,您可以執行unset ${(k)parameters}inzshunset -v $(compgen -v)in bash(儘管我發現我必須執行它兩次LINES才能COLUMNS消失)。

在我的測試中bash,仍然存在:

<noprompt> typeset -p
declare -r BASHOPTS="checkwinsize:cmdhist:complete_fullquote:expand_aliases:extquote:force_fignore:globasciiranges:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath"
declare -a BASH_ARGC=([0]="0")
declare -a BASH_ARGV=()
declare -a BASH_LINENO=()
declare -a BASH_SOURCE=()
declare -ar BASH_VERSINFO=([0]="5" [1]="0" [2]="17" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu")
declare -ir EUID="1000"
declare -a FUNCNAME
declare -x OLDPWD
declare -a PIPESTATUS=([0]="1")
declare -ir PPID="44873"
declare -r SHELLOPTS="braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor"
declare -ir UID="1000"
declare -- _="_"

並在zsh

<noprompt> printf '%s (%s)\n' ${(kv)parameters}
parameters (association-readonly-hide-hideval-special)
HISTCMD (integer-readonly-special)
! (integer-readonly-special)
# (integer-readonly-special)
$ (integer-readonly-special)
* (array-readonly-special)
- (scalar-readonly-special)
0 (scalar-special)
ZSH_EVAL_CONTEXT (scalar-readonly-tied-special)
ZSH_SUBSHELL (integer-readonly-special)
? (integer-readonly-special)
@ (array-readonly-special)
zsh_eval_context (array-readonly-tied-special)
status (integer-readonly-special)
TTYIDLE (integer-readonly-special)
LINENO (integer-readonly-special)
PPID (integer-readonly-special)
ARGC (integer-readonly-special)

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