위치 매개변수가 시작된다는 내용을 읽었습니다 $1
(예: $1
, $2
등은 $3
위치 매개변수입니다). 그러나 $0
위치 매개변수는 아닙니다.
그런데 왜 $0
위치 매개변수가 아닌가?
이것이 이유일 수도 있지만 확실하지는 않습니다.
위치 매개변수는 스크립트가 실행될 때만 해당 값을 갖습니다. 예를 들어 ./myScript Hello
, 이렇게 하면 $1
가치가 있을 것입니다 Hello
. 그러나 $0
그 값은 스크립트가 실행될 때(스크립트 이름의 값을 갖게 됨)와 bash
스크립트 없이 자체가 실행될 때( bash
또는 값을 갖게 됨 -bash
)의 두 가지 경우에 얻을 수 있습니다.
답변1
@ikkachu는 이미 설명했어요나보다 낫다. 그냥 역사 메모를 추가하는 중이에요.
Unix의 첫 번째 버전과 함께 제공된 셸(나중에 Thompson 셸이라고 함)에는 변수가 없었지만 이미 매개변수를 사용하여 간단한 스크립트를 작성할 수 있었습니다.
sh [ name [ arg1 ... [ arg9 ] ] ] The name is the name of a file which will be read and in‐ terpreted. If not given, this subinstance of the shell will continue to read the standard input file. In command lines in the file (not in command input), character sequences of the form "$n", where n is a digit 0, ..., 9, are replaced by the nth argument to the invo‐ cation of the shell (argn). "$0" is replaced by name.
$1
... $n
은(첫 번째 인수가 아님) 이미 $0
스크립트의 인수 및 이름이지만 호출되지는 않습니다.위치 매개변수그 다음에.
그 당시에는 $1
쉘에서 해석되기 전에 실제로 첫 번째 인수로 대체되었습니다.
예를 들어 스크립트에는 다음이 포함됩니다.
echo $1
~라고 불리는
sh script 'foo; echo bar'
실행할 수 있습니다 echo foo; echo bar
. 이 쉘은 수백 KB의 메모리를 가진 컴퓨터용으로 작성된 매우 간단한 쉘입니다.
약 10년 후(1970년대 후반), Bourne 쉘이 Unix 버전과 함께 등장하여 환경 및 기타 장점을 도입했습니다.
Bourne 쉘에는 변수와 더 많은 프로그래밍 구성이 함께 제공됩니다.
이것위치 매개변수적어도 Unix 쉘의 경우 이 용어는 Bourne 쉘에서 도입되었으며 스크립트에 사용되는 인수( $1
여전히 스크립트 이름임)와 동일한 것을 나타냅니다. Thompson 셸에서와 마찬가지로 위치 인수를 사용하여 처음 9개 인수( to )만 참조할 수 있습니다(그러나 나머지에 액세스하려면 Shift 또는 루프를 사용하세요)(이것은 또한 대부분의 최신 구현에서 Not이 필요한 이유를 설명합니다( 역방향 이식성 ) . 10번째).$n
$0
$1
$9
"$@"
for i do
${10}
$10
sh
이번에는 sh script 'foo; echo bar'
더 이상 echo bar
실행이 발생하지 않지만 Bourne 쉘은 여전히 악명 높은 분할+glob을 도입합니다. 이는 Thompson 쉘과의 하위 호환성을 크게 손상시키지 않으므로 파일 목록으로 여전히 호출할 수 있습니다 script 'foo *'
. 현재 디렉터리에서 인수로 가져옵니다(Thompson 셸에서와 같지만 이번에는 다른 메커니즘을 사용함).script
echo $1
echo
foo
스크립트라고도 불린다껍데기(Bourne 쉘에는 아직 기능이 없습니다):
2.0 Shell procedures The shell may be used to read and execute commands contained in a file. For example, sh file [ args ] calls the shell to read commands from file. Such a file is called a command procedure or shell procedure. Arguments may be supplied with the call and are referred to in file using the positional parameters $1, $2...
기능은 1980년대 초반 Korn 쉘(Bourne 쉘 기반)에 처음 도입되었습니다.
function foo {
...
}
통사론.
나중에 SysVR2(1984)에서는 다른 구문을 사용하여 Bourne 셸에 함수도 추가되었습니다.
foo() any-command
(그러나 단순한 명령이고 리디렉션이 있는 경우 예기치 않은 동작이 발생합니다. 이것이 아마도 POSIX가 가장 일반적으로 사용되는 명령과 같은 복합 명령만 인식하도록 POSIX가 요구하는 이유일 것입니다 any-command
.){ ...; }
sh
Korn 및 Bourne 쉘에서 $0
함수는 여전히 함수 이름이 아닌 스크립트 이름입니다(반면 $1
위치 $2
매개변수는 함수 매개변수를 참조함).
ksh93
이는 함수 내에서 함수 이름이 되는 함수 정의 스타일을 변경합니다 .function f {
$0
ksh93에서와 같이 함수 이름은 어디에 zsh
있습니까 ? 익명 기능도 도입되었습니다:$0
zsh
function { echo $1, $2; } foo bar
또는
(){ echo $1, $2; } foo bar
여기서 구문은 $0
/emulation 에 있을 때 스크립트 이름을 유지합니다 (anon)
.set +o functionargzero
sh
ksh
에서 zsh
와 마찬가지로 csh
스크립트의 인수는 배열에 있으므로 $argv
인수 이름 지정과 유사한 프로그램 이름이 복잡해지지 않습니다.
여기에서 다음을 사용하여 위치 매개변수에 값을 할당할 수 있습니다.
argv[1]=value
또는
1=value
( 0=newprogramname
프로그램 이름을 변경할 수도 있습니다).
Bourne과 같은 다른 쉘에서는 모든 것을 한 번에 할당해야 합니다 set
.
set -- arg1 arg2
그리고 당신은 그것을 변경할 수 없습니다 $0
.
rc
(적어도 공개 도메인 복제 에서는 ) 다음을 수행할 수 없습니다.
1 = value
하지만 다음과 같이 할 수 있습니다.
* = (arg1 arg2)
위치 매개변수를 설정합니다. $0
에서는 변경할 수 없지만 like in 을 사용하여 파생물을 변경할 rc
수 있습니다 .es
0=newprogramname
zsh
긴 이야기 짧게
, $1
... $2
Thompson 셸에서 나오지만 호출되지 않는 스크립트 인수를 나타냅니다.위치 매개변수하지만. 그리고 $0
(아마도 @ikkachu가 말한 것과 관련하여 argv[0]
) 스크립트 이름을 나타냅니다.
이것위치 매개변수이 용어는 Bourne Shell에서 유래되었습니다.
$0
스크립트의 매개변수를 참조하지 않으므로 위치 매개변수가 아닙니다. 이는 스크립트의 이름을 나타냅니다( argv[0]
쉘이 스크립트를 실행하지 않을 때는 쉘의 이름을 나타냅니다. 일부 쉘에서는 함수 내에서 사용될 때 함수의 이름을 나타냅니다).
답변2
번호가 매겨진 매개변수( $0
, $1
, ...) argv[]
는 프로세스가 시작될 때 명령줄 매개변수를 포함하는 배열과 명백히 유사합니다. 배열의 첫 번째 요소는 argv[0]
일반적으로 프로세스의 이름을 가지며 실제 매개변수는 거기에서 시작됩니다 argv[1]
.
(보통. 꼭 그럴 필요는 없습니다.execve(2)
상태 설명: "값은argv[0]
~해야 한다시작되는 프로세스와 관련된 파일 이름 문자열에 대한 포인터")
적어도 돌이켜보면 이 규칙이 단순히 쉘에 직접 복사되었다는 것을 상상하기 쉽습니다.
그러나 이러한 값은 직접 복사되지 않습니다. 적어도 내 시스템에서는 ./script.sh
hashbang이 실행될 때 시작된 셸 프로세스를 사용하여 #!/bin/bash -x
매개 변수 /bin/bash
, -x
, 를 가져옵니다 ./script.sh
. 즉, $0
스크립트에서 보는 값은 argv[2]
쉘 프로세스에 있습니다.
나는 대부분의 사람들이 명령 이름을 인수와 별개로 생각할 것이라고 가정합니다 $0
.기능적으로남들과 다르기 때문에 다르게 불러도 무리가 없습니다.
물론 다른 명명 규칙을 사용하는 스크립팅 언어를 사용할 수도 있습니다. Perl은 프로그램 이름을 명명된 변수에 넣고 인수를 인덱스 0부터 시작하는 $0
배열에 넣습니다 .@ARGV
$ARGV[0]
어쨌든 가장 확실한 대답은 이것이 $0
위치 매개변수가 아니라는 것입니다.표준에 그렇게 나와있으니까:
2.5.1 위치 매개변수
위치 매개변수는 하나 이상의 숫자(한 자리 0 제외)로 표시되는 10진수 값으로 표시되는 매개변수입니다.
2.5.2 특수 매개변수
#
위치 인수의 10진수로 확장합니다. 명령 이름(인수 0)은#
위치 인수가 아닌 특수 인수이므로 " "로 주어진 숫자에 포함되어서는 안 됩니다.
0
(0.) 쉘 또는 쉘 스크립트의 이름으로 확장됩니다.
답변3
$0 는 실제로 위치 인수입니다(아래 Michael Homer의 설명에서 지적했듯이 POSIX는 "... 인수 이름을 1부터 n까지 번호가 지정된 위치 인수로 취하고 명령 이름(또는 함수의 경우)을 사용합니다. 스크립트에서는 스크립트 이름)위치 매개변수 번호가 0인 경우".
예상할 수 있듯이 이는 호출 명령의 이름을 나타내는 위치 0의 매개변수입니다.
이는 동일한 스크립트가 호출 이름에 따라 다르게 동작할 수 있도록 하여 동일한 실행 파일이 여러 기능(예를 들어 심볼릭 링크 등)을 가질 수 있도록 하기 때문에 유용합니다. 이를 통해 프로세스는 호출 이름이 무엇인지 알 수 있습니다.
/bin을 잠깐 살펴보면 bzcat, bzcmp, bzip2, ..., mdir, mcat, mcd, mdel, ... 등의 많은 예를 볼 수 있습니다. . 프로세스가 수행할 기능을 아는 방법은 위치 매개변수 0을 확인하는 것입니다.
참고: 일부 쉘 매뉴얼 페이지에서는 용어를 다르게 취급할 수 있습니다. bash의 매뉴얼 페이지에서는 위치 매개변수가 아니라고 말하고 ksh의 매뉴얼 페이지(및 POSIX 정의)에서는 그렇다고 말합니다. 용어 논의에 관계없이 (bash 및 ksh) $0에는 호출 명령 또는 스크립트의 이름이 포함됩니다. 대화형 셸인 경우 $0에는 프로세스 이름이므로 셸 이름(bash, ksh...)이 포함됩니다.