환경 변수 및 위치 매개변수

환경 변수 및 위치 매개변수

쉘에는 $0, $1, 등과 같은 변수가 있습니다 $2.$?

다음을 사용하여 셸 및 환경 변수를 인쇄해 보았습니다.

set

그러나 이러한 변수는 목록에 없습니다.

따라서 기본적으로 이러한 변수는 쉘/환경 변수로 간주되지 않습니다. 그렇죠? (출력할 때도 $쉘/환경 변수와 마찬가지로 앞에 추가해야 합니다 )

답변1

변수는 쉘에 있는 세 가지 유형의 매개변수 중 하나입니다.

  1. 바꾸다_이름이 문자 또는 로 시작하고 그 뒤에 0개 이상의 문자, 숫자 또는 가 _오는 유효한 쉘 식별자인 매개변수입니다.
  2. 이것위치상의매개변수는 번호가 매겨진 매개변수입니다 $1, $2, ...
  3. 이것특별한$0매개변수는 다양한 구두점을 제외하고 모두 단일 문자 이름입니다 .

set쉘 변수만 표시됩니다.

셸 변수의 하위 집합은 환경 변수로, 해당 값은 셸이 시작될 때 환경에서 상속되거나 export유효 이름에 대한 속성을 설정하여 생성됩니다.

답변2

환경 변수 및 위치 매개변수

변수 유형에 대해 논의하기 전에 $INTEGER변수 유형이 정확히 무엇인지, 환경 변수와 어떻게 다른지 이해해야 합니다. 예를 들어 변수를 $INTEGER위치 매개변수라고 합니다. 이는 POSIX(Portable Operating System Interface) 표준에 설명되어 있습니다.섹션 2.1(강조):

  1. 쉘은 함수(함수 정의 명령 참조), 내장 함수(특수 내장 유틸리티 참조), 실행 파일 또는 스크립트를 실행합니다.매개변수 이름을 1부터 n까지의 위치 인수로 지정하고 명령 이름(또는 스크립트 내의 함수의 경우 스크립트 이름)을 위치 인수 번호 0으로 지정합니다.(명령 검색 및 실행 참조)

$HOME대조적으로, 및 와 같은 변수 $PATH는 환경 변수입니다. 해당 정의는 다음에 설명되어 있습니다.표준 제8조:

이 장에 정의된 환경 변수는 여러 유틸리티, 기능 및 응용 프로그램의 작동에 영향을 미칩니다. 특정 유틸리티에만 관심이 있는 다른 환경 변수가 있습니다. 단일 유틸리티에만 적용되는 환경 변수는 유틸리티 설명의 일부로 정의됩니다.

설명에 주의하세요. 위치 인수는 명령 앞에 나타나야 합니다(예: ) command positional_arg_1 positional_arg_2.... 명령에 수행할 작업을 정확하게 알려주기 위해 사용자가 제공합니다. 이렇게 하면 및 문자열이 echo 'Hello' 'World'인쇄됩니다. 이는 작업하려는 항목의 위치 매개변수이기 때문입니다. 위치 인수를 인쇄할 문자열로 이해하도록 구축되었습니다(와 같은 선택적 플래그 중 하나가 아닌 경우). 다른 명령으로 이 작업을 수행하면 숫자가 예상될 수 있으므로 무엇과 무엇인지 이해하지 못할 수 있습니다. 위치 매개변수는 "상속"되지 않습니다. 즉, 자식 프로세스에 명시적으로 전달되지 않는 한 자식 프로세스는 부모 프로세스의 위치 매개변수를 알 수 없습니다. 종종 래퍼 스크립트를 사용하여 전달된 위치 인수를 볼 수 있습니다. 이러한 스크립트는 명령의 기존 인스턴스를 확인하거나 호출될 실제 명령에 추가 위치 인수를 추가할 수 있습니다.HelloWorldechoechoecho-nHelloWorld

대조적으로, 환경 변수는 여러 프로그램에 영향을 미치도록 설계되었습니다. 그들은환경변수는 프로그램 자체 외부에서 설정되기 때문입니다(자세한 내용은 아래 참조). 일부 환경 변수(예: HOME또는 ) PATH는 특정 형식, 특정 의미를 가지며 모든 프로그램에서 동일한 의미를 갖습니다. 변수는 외부 유틸리티나 쉘(및 스크립트)에 대해 동일한 의미를 갖습니다. 즉, HOME프로세스가 실행 중일 때 사용자 이름의 홈 디렉터리입니다. /usr/bin/find환경 변수는 특정 명령 동작을 설명하는 데 사용될 수 있습니다. 예를 들어 UID환경 변수는 스크립트가 루트 권한으로 실행되고 그에 따라 특정 작업으로 분기되는지 확인하는 데 사용될 수 있습니다. 환경 변수는 상속 가능합니다. 하위 프로세스는 상위 프로세스 환경의 복사본을 가져옵니다. 당신은 또한 볼 수 있습니다프로세스가 상위 프로세스의 환경을 상속하는 경우 이를 내보내야 하는 이유는 무엇입니까?

간단히 말해서, 환경 변수는 명령 외부에서 설정되어 일반적으로 변경되지 않는 반면, 위치 매개변수는 명령에 의해 처리되어 변경되는 것입니다.


단순한 쉘 개념 그 이상

나는 당신이 터미널과 쉘을 혼동했다는 의견을 보았으므로 꼭 읽어 보시기를 권합니다.실제 터미널옛날에는 물리적 장치였습니다. 오늘날 우리가 일반적으로 "터미널"이라고 부르는 검은색 배경과 녹색 텍스트가 있는 창은 실제로는 소프트웨어, 즉 프로세스입니다. 터미널은 쉘을 실행하는 프로그램이고 쉘도 프로그램이지만 실행하기 위해 입력한 내용을 읽습니다(즉, 대화형 쉘인 경우 비대화형 쉘은 스크립트 및 sh -c 'echo foo'호출 유형입니다). 조개에 대한 추가 정보여기.

이는 중요한 차이점이지만 터미널이 프로그램이므로 동일한 환경 및 위치 인수 규칙을 따른다는 점을 인식하는 것도 중요합니다. 시작 시 환경 변수를 gnome-terminal살펴보고 SHELL를 사용하지 않는 한 적절한 기본 셸을 생성합니다 -e. 기본 셸을 대신 ksh gnome-terminal 로 변경한다고 가정하면 이는 프로그램이 환경을 사용할 수 있는 방법에 대한 예이기도 합니다. 특정 쉘을 실행하라고 명시적 으로 지시하면 이 작업이 수행되지만 영구적이지는 않습니다. 대조적으로, 환경은 본질적으로 변경되지 않습니다(나중에 자세히 설명).kshbashgnome-terminal-e

보시다시피 환경 변수와 위치 변수는 모두 셸뿐만 아니라 프로세스/명령의 속성입니다. 쉘 스크립트의 경우 C 프로그래밍 언어로 설정된 모델도 따릅니다. C 함수를 예로 들면 main일반적으로 다음과 같습니다.

int main(int argc, char **argv)

, 실제로 명령줄 인수의 배열인 명령줄 인수 argc의 수는 어디에 있으며, 사용자의 홈 디렉터리 경로, 실행 파일을 찾을 수 있는 디렉터리 목록 등에 액세스하는 함수(Linux의 경우 )가 있습니다. . 쉘 스크립트도 비슷한 방식으로 모델링됩니다. 쉘 용어로는 위치 매개변수 등이 있지만 오히려 위치 매개변수의 개수가 있습니다. 무엇에 대해? 이는 C 프로그래밍 언어에서 모델링된 실행 파일 자체의 이름입니다. C "실행 파일"의 이름이 됩니다. 이는 다음과 같은 경우에 유용합니다.argvenvironman -e 7 environPATH$1$2$#$0argv[0]대부분의 프로그래밍 및 스크립팅 언어.

대화형 셸과 비대화형 셸

제가 이미 암시한 한 가지는 다음과 같은 차이점입니다.대화형 및 비대화형 쉘. 명령을 입력하는 프롬프트 - 이는 대화형이며 사용자와 상호 작용합니다. 대조적으로, 쉘 스크립트가 있거나 이를 실행하면 bash -c''비대화형입니다.

여기서 구별이 중요해집니다. 실행한 셸은 위치 인수( bash로그인 셸의 경우 "...인수 0의 첫 번째 문자는 - 또는 --login 옵션으로 시작하는 문자입니다.")를 사용하여 생성된 프로세스입니다. (인용하다) )

대조적으로, 옵션으로 시작되는 스크립트와 쉘은 및 인수를 -c활용할 수 있습니다 . 예를 들어,$1$2

$ bash -c 'echo $1; stat $2' sh 'Hello World' /etc/passwd
Hello World
  File: '/etc/passwd'
  Size: 2913        Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 6035604     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2017-08-12 14:48:37.125879962 -0600
Modify: 2017-08-12 14:48:37.125879962 -0600
Change: 2017-08-12 14:48:37.137879811 -0600
 Birth: -

sh옵션의 약간 특이한 점 -c은 첫 번째 위치 인수를 가져와 $0일반적인 프로그램 이름이 아닌 에 할당한다는 것입니다.

주목해야 할 또 다른 중요한 점은 위치 매개변수를 "프레임 가능"이라고 부르는 것입니다. bash먼저 자체 위치 인수로 시작하지만 이러한 위치 인수는 및 echo에 대한 인수 가 됩니다 stat. 각 프로그램은 고유한 방식으로 이를 이해합니다. stat문자열이 주어지고 Hello World파일이 없으면 Hello World오류가 생성됩니다. bash이는 단순한 문자열로 처리되지만 stat문자열은 기존 파일 이름일 것으로 예상됩니다. 대조적으로, 모든 프로그램은 환경 변수가 HOME디렉토리라는 점에 동의합니다(프로그래머가 비합리적인 방식으로 코딩하지 않는 한).


환경 변수와 위치 매개변수를 조작할 수 있나요?

기술적으로는 둘 다 처리할 수 있지만해서는 안 된다환경 변수를 사용하면 위치 인수를 제공해야 하는 경우가 많습니다. 셸에서 명령을 실행하고 앞에 변수를 추가할 수 있습니다. 예를 들면 다음과 같습니다.

$ hello=world bash -c 'echo $hello'
world

export variable=value또한 셸이나 스크립트 내에서 변수를 사용하여 환경에 변수를 넣을 수도 있습니다. 또는 완전히 비어 있는 환경에서 명령을 실행할 수도 있습니다 env -c command arg1 arg2. 그러나 일반적으로 환경을 엉망으로 만드는 것은 권장되지 않습니다. 특히 대문자 변수를 사용하거나 기존 환경 변수를 덮어쓰는 것은 권장되지 않습니다. 이는 권장 사항이지만 표준은 아닙니다.

위치 매개변수의 경우 이를 설정하는 확실한 방법은 명령에 추가하는 것이지만 다른 방법도 있습니다.다른 방법으로 설정, shift명령을 통해 변경할 수 있는 매개변수 목록입니다.

대체로 둘 다 다른 목적을 가지고 있지만 이유가 있습니다. 사람들이 이 답변을 통해 통찰력을 얻을 수 있기를 바랍니다. 제가 쓴 것만큼 읽는 것도 재미있습니다.


명령 설정에 관한 참고 사항

매뉴얼에 따르면 set명령은 다음과 같이 작동합니다(bash 매뉴얼에서 강조가 추가됨).

옵션 없음, 각 옵션의 이름 및 값쉘 변수현재 설정된 변수를 설정하거나 재설정하기 위한 입력으로 반복적으로 사용할 수 있는 형식으로 표시됩니다.

즉, set쉘 특정 변수를 살펴보십시오. 그 중 일부는 환경에 있습니다 HOME. 예를 들어, 와 같은 명령은 env명령 printenv이 실행될 때 사용되는 실제 환경 변수를 살펴봅니다. 당신은 또한 볼 수 있습니다이것.

답변3

이러한 $1, $2, $3, ..., ${10}, ${11}변수를 위치 매개변수라고 하며 bash 매뉴얼 섹션에 설명되어 있습니다.3.4.1

3.4.1 위치 매개변수

위치 매개변수는 단일 숫자 0이 아닌 하나 이상의 숫자로 표시되는 매개변수입니다. 위치 인수는 쉘이 호출될 때 쉘의 인수에서 할당되며 set 내장 명령을 사용하여 다시 할당될 수 있습니다. 위치 매개변수 N은 ${N}으로 인용되거나 N이 단일 숫자로 구성되는 경우 $N으로 인용될 수 있습니다. 위치 매개변수는 할당문을 사용하여 할당할 수 없습니다. set 및 Shift 내장 명령은 이를 설정하고 설정 해제하는 데 사용됩니다(셸 내장 명령 참조). 위치 매개변수는 쉘 함수가 실행될 때 일시적으로 대체됩니다(쉘 함수 참조).

두 개 이상의 숫자로 구성된 위치 인수를 확장하는 경우 중괄호로 묶어야 합니다.

$?와 에 관해서는 $0, 이것들은특수 매개변수다음 섹션에서 소개하겠습니다.3.4.2

3.4.2 특수 매개변수

쉘은 여러 매개변수를 특별히 처리합니다. 이러한 매개변수는 참조용일 뿐이며 이에 대한 할당은 허용되지 않습니다.

...

?

($?) 가장 최근에 실행된 전경 파이프의 종료 상태로 확장됩니다.

0

($0)은 쉘 또는 쉘 스크립트의 이름으로 확장됩니다. 이는 쉘이 초기화될 때 설정됩니다. Bash가 명령 파일(셸 스크립팅 참조)을 사용하여 호출되면 $0이 파일 이름으로 설정됩니다. Bash가 -c 옵션(Bash 호출 참조)으로 시작되면 $0은 실행될 문자열 뒤의 첫 번째 인수(있는 경우)로 설정됩니다. 그렇지 않으면 인수 0으로 지정된 대로 Bash를 호출하는 데 사용되는 파일 이름으로 설정됩니다.

답변4

아니요, 이는 스크립트의 매개변수입니다. 예를 들어, 다음과 같이 스크립트를 호출하면:

mynicescript.sh one two three

그러면 스크립트에서 이러한 매개변수를 다음과 같이 사용할 수 있습니다.

$1 = one
$2 = two
$3 = three

$0은 스크립트 자체의 이름입니다.

따라서 스크립트 외부에 있을 때는 이러한 변수를 사용할 수 없습니다(셸 자체인 /bin/bash를 표시하는 $0 제외).

관련 정보