나는 다음과 같은 관련 질문을 보았습니다.이것하지만 그들은 내 질문에 대한 정확한 답을 제공하지 않았습니다
내 실험에서도이 답변, printenv
거의 env
동일한 시스템 변수 세트를 표시합니다.
변수를 다음으로 설정하면
/etc/bash.bashrc (시스템 전체 시스템 변수여야 함)
SYSTEM_ENVI=1000
~/.bashrc (사용자별 시스템 변수에 사용해야 함)
USER_ENVI=10
/etc/environment가 적용되도록 로그아웃했다가 로그인하기도 했습니다. 다음 시나리오가 발생합니다.
$echo $SYSTEM_ENVI
//outputs 1000
$echo $USER_ENVI
//outputs 10
$CURR_ENVI=1
$env | grep USER_ENVI
//nothing shows up, the same if I grepped SYSTEM_ENVI or CURR_ENVI
$set | grep USER_ENVI
//shows up USER_ENVI assignment, the same if I grepped SYSTEM_ENVI or CURR_ENVI
내 질문은 다음과 같습니다
printenv
어떤 시스템 변수가 실행/인쇄됩니까env
?- 또는
set
대신 액세스 가능한 모든 변수(시스템 변수 및 지역 변수)를 사용해야 합니까 ?printenv
env
반복하지 않는 이유
내 경우에는 이 질문과 표시된 답변이 다음 사실을 깨닫는 데 도움이 되었습니다.
- 쉘 변수는 환경 변수가 아닙니다
- 작업/etc/bash.bashrc또는~/.bashrc환경 변수를 생성하지 말고 대화형 비로그인 셸 프로세스에 이러한 변수를 생성하고 초기화하도록 지시하십시오.쉘 변수스타트업에 대하여.
내 질문이 반드시 다음과 관련이 있다고 생각하지 않습니다.이것하지만 이 질문에 표시된 답변을 읽는 것은 이 게시물에 제공된 답변만큼 만족스럽지 못했습니다.
답변1
env
그리고 printenv
이를 실행하는 명령에 의해 제공되는 환경 문자열 목록(환경 변수 정의를 포함하도록 의도됨)을 인쇄합니다. 호출자는 결국 다음을 수행합니다.
execve("/usr/bin/env", argv, envp);
argv
여기서 및 envp
는 두 개의 문자열 목록인 시스템 호출 입니다.
env
/ printenv
의 문자열 목록만 한 envp
줄에 하나씩 인쇄합니다.
관례에 따라 의 문자열은 envp
형식으로 되어 있지만 var=value
반드시 그럴 필요는 없으며( execve()
이를 강제하는 구현에 대해서는 알지 못합니다) 대부분의 env
구현에서는 printenv
문자열을 언제 표시할지 신경 쓰지 않습니다.
호출자가 POSIX 쉘인 경우 표시된 쉘 envp
에 전달된 변수 목록 에 포함됩니다.env
출구(사용자가 export
/를 호출 typeset -x
했거나 변수가 쉘이 시작될 때 수신된 환경에 이미 있기 때문입니다).
시작 시 쉘이 수신한 일부 환경 변수를 쉘 변수에 매핑할 수 없거나 envp
수신한 문자열에 =
문자가 포함되어 있지 않은 경우 쉘 구현에 따라 이러한 문자열은 영향을 받지 않고 전달됩니다. 그렇지 않으면 쉘은 해당 문자열을 Go에서 제거합니다. 아니면 그 중 일부.
예를 들어 bash
, GNU를 사용하면 env
임의의 변수 이름 목록을 전달할 수 있습니다( env
그러나 임의의 envp 문자열은 허용되지 않으며 a를 포함해야 하며 =
사용된 문자열은 1로 시작하는 변수를 setenv()
전달할 수 없습니다 =
).
$ env -i '=foo' '1=x' '+=y' bash -c printenv
+=y
1=x
[...]
(이름이 비어 있는 변수는 삭제되지만, 다른 변수는 삭제되지 않습니다.)
또한 쉘이 envp
동일한 변수 이름에 대해 여러 문자열을 수신하는 경우 쉘에 따라 모두 전달되거나 첫 번째 문자열만 전달되거나 마지막 문자열만 전달됩니다.
set
내보내기 표시 여부에 관계없이 배열/해시 유형을 지원하는 셸의 비스칼라 변수를 포함하여 POSIX 셸의 셸 변수 목록을 인쇄합니다.
POSIX 셸에서는 이를 사용하여 export -p
내보내기용으로 표시된 변수를 나열할 수도 있습니다. env
/ 와 달리 printenv
내보낸 것으로 표시되었지만 아직 값이 할당되지 않은 변수도 나열됩니다.
또는 ksh
와 같은 Korn 유사 셸에서 를 사용하여 변수 속성을 포함한 추가 정보를 얻고 유형별로 변수를 나열할 수도 있습니다 (예: 배열 변수 나열).zsh
bash
typeset
typeset -a
여기에서 USER_ENVI=10
다음을 추가하여 ~/.bashrc
셸의 대화형 비로그인 호출을 bash
구성 할 수 있습니다.USER_ENVI
껍데기시작 시 변수. 사용하지 않았으므로 export
변수는 여전히 셸 변수이므로(시작 시 환경에 있지 않는 한 bash
) 다음과 같이 사용되지 않습니다.환경이 셸에서 실행되는 명령에 대한 변수입니다.
/etc/environment
Ubuntu 16.04의 플러그형 인증 모듈에서 기본적으로 읽습니다 pam_env.so
. 로그인 응용 프로그램(예: login
, sshd
, , )은 lightdm
이러한 파일을 읽습니다( 해당 파일을 사용 pam_env.so
하고 전달하도록 구성된 경우)./etc/pam.d
환경변수(여기서 쉘 변수와 관련 없음)는 인증 후 사용자 이름으로 실행되는 명령(예: login
/의 로그인 쉘 sshd
또는...의 그래픽 세션 관리자 lightdm
)입니다.
환경은 기본적으로 상속되므로 세션 관리자가 터미널 에뮬레이터를 실행하면(로그인 쉘이 실행됨) 이러한 환경 변수는 각 단계에서 전달되고 쉘은 확장할 수 있는 쉘 변수에 매핑됩니다. 와 같은 명령과 일치합니다 echo "$VAR"
.
pam_env
env 파일은 /etc/environment
쉘 스크립트처럼 보이지만 pam_env
이를 구문 분석하기 위해 쉘이 호출되지 않으며 쉘 구문의 하위 집합만 이해되며 이름이 하나 이상의 ASCII 영숫자 문자 또는 밑줄로 구성된 변수의 정의만 허용합니다. 123
유효한 POSIX 쉘 변수 이름이 아니더라도 변수를 정의할 수 있습니다 .
1. 임의의 환경 문자열 목록을 전달하려면 execve()
다음과 같이 직접 호출할 수도 있습니다.
perl -e 'require "syscall.ph";
$cmd = "/bin/zsh";
$args = pack("p*x[p]", "sh", "-c", "printenv");
$env = pack("p*x[p]", "a=b", "a=c", "", "+=+", "=foo", "bar");
syscall(SYS_execve(), $cmd, $args, $env)'
zsh
대신 여기에서 테스트하세요 .bash
답변2
다음을 수행하여:
USER_ENVI=10
변수를 설정하고 있지만 환경 변수는 설정하지 않습니다. 이렇게 하려면 다음이 필요합니다.
export USER_ENVI=10
또는
USER_ENVI=10; export USER_ENVI
그것은 합리적입니다. 이것은 당신에게 효과가 없습니다:
$ env | grep SYSTEM_ENVI
set 이라는 환경 변수가 없습니다 SYSTEM_ENVI
. /etc/environment
귀하는 콘텐츠를 게시하지 않았으며 사용하지도 않는 것으로 보이므로 이에 대해 드릴 말씀이 없습니다 .
env
인쇄해야 할 내용을 정확하게 인쇄합니다 printenv
(옵션 없음).
답변:
env와 printenv는 모두 실제로 설정된 것과 정확히 동일한 변수 목록을 보고합니다.투자 기금명령 뒤에는 옵션이나 변수 목록이 없습니다.
set(옵션 없이)을 사용하면 모든 변수 세트를 볼 수 있습니다. 이것은 당신을 의미하지 않습니다~ 해야 하다그걸 써. 그것은 당신이 나열하고 싶은 것에 달려 있습니다. 환경 변수 목록을 만드는 것만으로도 완벽하게 유효하고 정확합니다.