env 및 printenv는 어떤 환경/셸 변수를 보여줍니다.

env 및 printenv는 어떤 환경/셸 변수를 보여줍니다.

나는 다음과 같은 관련 질문을 보았습니다.이것하지만 그들은 내 질문에 대한 정확한 답을 제공하지 않았습니다

내 실험에서도이 답변, printenv거의 env동일한 시스템 변수 세트를 표시합니다.

변수를 다음으로 설정하면

  1. /etc/bash.bashrc (시스템 전체 시스템 변수여야 함)

    SYSTEM_ENVI=1000
    
  2. ~/.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

내 질문은 다음과 같습니다

  1. printenv어떤 시스템 변수가 실행/인쇄됩니까 env?
  2. 또는 set대신 액세스 가능한 모든 변수(시스템 변수 및 지역 변수)를 사용해야 합니까 ?printenvenv

반복하지 않는 이유

내 경우에는 이 질문과 표시된 답변이 다음 사실을 깨닫는 데 도움이 되었습니다.

  1. 쉘 변수는 환경 변수가 아닙니다
  2. 작업/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 유사 셸에서 를 사용하여 변수 속성을 포함한 추가 정보를 얻고 유형별로 변수를 나열할 수도 있습니다 (예: 배열 변수 나열).zshbashtypesettypeset -a

여기에서 USER_ENVI=10다음을 추가하여 ~/.bashrc셸의 대화형 비로그인 호출을 bash구성 할 수 있습니다.USER_ENVI 껍데기시작 시 변수. 사용하지 않았으므로 export변수는 여전히 셸 변수이므로(시작 시 환경에 있지 않는 한 bash) 다음과 같이 사용되지 않습니다.환경이 셸에서 실행되는 명령에 대한 변수입니다.

/etc/environmentUbuntu 16.04의 플러그형 인증 모듈에서 기본적으로 읽습니다 pam_env.so. 로그인 응용 프로그램(예: login, sshd, , )은 lightdm이러한 파일을 읽습니다( 해당 파일을 사용 pam_env.so하고 전달하도록 구성된 경우)./etc/pam.d환경변수(여기서 쉘 변수와 관련 없음)는 인증 후 사용자 이름으로 실행되는 명령(예: login/의 로그인 쉘 sshd또는...의 그래픽 세션 관리자 lightdm)입니다.

환경은 기본적으로 상속되므로 세션 관리자가 터미널 에뮬레이터를 실행하면(로그인 쉘이 실행됨) 이러한 환경 변수는 각 단계에서 전달되고 쉘은 확장할 수 있는 쉘 변수에 매핑됩니다. 와 같은 명령과 일치합니다 echo "$VAR".

pam_envenv 파일은 /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(옵션 없음).

답변:

  1. env와 printenv는 모두 실제로 설정된 것과 정확히 동일한 변수 목록을 보고합니다.투자 기금명령 뒤에는 옵션이나 변수 목록이 없습니다.

  2. set(옵션 없이)을 사용하면 모든 변수 세트를 볼 수 있습니다. 이것은 당신을 의미하지 않습니다~ 해야 하다그걸 써. 그것은 당신이 나열하고 싶은 것에 달려 있습니다. 환경 변수 목록을 만드는 것만으로도 완벽하게 유효하고 정확합니다.

관련 정보