/usr/bin/env -i /bin/bash --norc --noprofile 이후 PATH가 비어 있지 않습니다.

/usr/bin/env -i /bin/bash --norc --noprofile 이후 PATH가 비어 있지 않습니다.

다음 결과를 이해할 수 없습니다.

/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그래서 없다환경, 그러나 여전히 null이 아닌 PATH변수를 정의하고 쉘은 이를 사용하여 명령을 구문 분석할 수 있습니다.

bash-5.0$ which ls
/bin/ls

나는 다음과 같이 강제 로 null을 /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에서 ​​완전히 사라지는 것이 좋습니다. 2) 위의 상황은 나중에 생성된 셸 세션의 많은 변수가 여전히 정의되어 있습니다 ./usr/bin/printenvPATH/usr/bin/env -i

묻다:/bin/bash환경에 관계없이 정의된 변수를 가능한 한 적게 사용하여 대화형 세션을 시작하는 가장 간단한 방법은 무엇입니까? 1

(이 질문을 표현하기 위해 이 단어를 사용했지만 bash그에 대한 관련 정보에도 관심이 있습니다 zsh.)


1일부 변수가 정의되지 않으면 많은 프로그램이 제대로 실행되지 않거나 전혀 실행되지 않는다는 것을 알고 있습니다 . 문제 해결, 진단 등 이외의 용도로 이러한 작은 쉘 세션을 사용할 생각은 없습니다.

답변1

예, 시작 시 수신된 환경에서 제공되지 않은 경우 bash둘 다 zsh(및 dash최소한 ) mksh가 기본값으로 설정됩니다.fish$PATH

지원되지 않는 POSIX 쉘은 여전히 ​​기본 검색 경로에서 명령을 찾아야 합니다.

및 ( bashzsh자동으로 로드되거나 후자에 로드되지 않는 일부 모듈)은 여러 내부 변수를 설정합니다. 그 중 일부는 환경으로 내보내지고( PATH및 의 경우는 아님) 일부는 읽기 전용입니다.bashzsh

env -i zsh -f또는 env -i bash --norc쉘이 빈 환경에서 실행됩니다.

읽기 전용이 아닌 설정을 해제하려면 unset ${(k)parameters}in zsh또는 unset -v $(compgen -v)in에서 수행할 수 있습니다(비록 사라지 bash려면 두 번 실행해야 한다는 것을 알았지만 ).LINESCOLUMNS

내 테스트에서는 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)

답변2

envvar가 정의되지 않은 경우 모든 쉘은 "기본" 경로(일반적으로 최소한 /bin및 포함 /usr/bin)를 사용하여 명령을 찾습니다. PATH이 동작은 또한 복제되었습니다 execvp(2).

일부 껍질(예:세게 때리다)은 이 경우 PATH쉘 변수를 기본 경로로 설정합니다 .

/bin/bash환경에 관계없이 정의된 변수를 가능한 한 적게 사용하여 대화형 세션을 시작하는 가장 간단한 방법은 무엇입니까?

env - bash --norc

bash-5.0$ which ls

which내장된 bash가 아닙니다. 일부 시스템에서는 bash가 실행하는 쉘 스크립트입니다.다른쉘은 bash보다 낫습니다. 여기서는 전혀 관련이 없습니다.

관련 정보