스크립트에 인수 전달

스크립트에 인수 전달

저는 Linux Essentials 수업을 듣고 있으며 스크립팅 장에 도달할 때까지 잘 지내고 있었습니다. 나는 이러한 개념을 이해하지 못합니다. 누군가 다음 내용을 매우 단순한 용어로 분류하거나 이를 배울 수 있는 더 나은 참고 자료를 알려줄 수 있는지 궁금합니다. 저는 현재 netacad의 커리큘럼을 사용하고 있습니다.


교과서에서(사소한 형식 변경 포함):

사용자가 설정한 변수 외에도 몇 가지 특수 변수가 있습니다. 스크립트에 인수를 전달할 수 있습니다.

#!/bin/bash
echo "Hello $1"

달러 기호 뒤에 숫자 N이 오면 스크립트에 전달된 N번째 인수에 해당합니다. 위의 예제를 호출하면 ./test.sh출력은 Hello Linux가 됩니다. 변수 $0에는 스크립트 자체의 이름이 포함됩니다.

바이너리든 스크립트든 프로그램이 실행된 후 0에서 255 사이의 정수인 종료 코드를 반환합니다. 변수를 통해 이를 테스트하여 $?이전 명령이 성공적으로 완료되었는지 확인할 수 있습니다.


변수를 할당하는 방법과 변수가 어떻게 작동하는지 이해 하지만 and $의 전체 문제는 이해할 수 없습니다. $0$1

어떤 도움이라도 주시면 감사하겠습니다.

답변1

책의 설명이 잘못되었습니다(또는 적어도 뭔가 빠졌습니다). 해당 스크립트를 "Hello Linux"로 인쇄하려면 다음과 같이 실행합니다.

./test.sh Linux

just 로 실행하면 ./test.sh첫 번째 인수가 없고 $1정의되지 않았기 때문에 "Hello"만 인쇄됩니다. 반면에 다음과 같이 실행했다고 가정해 보겠습니다.

./test.sh foo bar baz

그러면 스크립트 내에서는 $0"./test.sh", $1"foo", $2"bar", $3"baz"가 됩니다.

의 경우 $?다음 스크립트 조각을 고려하세요.

ls nonexistentfile.txt
echo "The exit status of ls was: $?"
echo "The exit status of echo (the first one) was: $?"

실행하면 다음과 같이 인쇄됩니다.

ls: nonexistentfile.txt: No such file or directory
The exit status of ls was: 1
The exit status of echo (the first one) was: 0

ls명령은 nonexistentfile.txt를 나열할 수 없으므로(존재하지 않기 때문에) 해당 효과에 대한 오류 메시지를 인쇄하고 문제가 발생했음을 나타내기 위해 0이 아닌 상태로 종료됩니다. 첫 번째 echo명령은 종료 상태( $?)를 인쇄하고 성공적으로 수행했으므로 상태 0으로 종료됩니다. 두 번째 명령이 실행되면 첫 번째 명령에서 echo가져오므 로 "0"이 인쇄됩니다.$?echo

그런데, 많은 명령은 종료 상태 0(성공) 또는 1(일종의 실패)을 사용하지만 일부는 정확히 무엇이 잘못되었는지 나타내기 위해 다른 실패 상태를 사용합니다. 다음은curl매뉴얼 페이지:

EXIT CODES
       There are a bunch of different  error  codes  and  their  corresponding
       error  messages  that  may appear during bad conditions. At the time of
       this writing, the exit codes are:

       1      Unsupported protocol. This build of curl has no support for this
              protocol.

       2      Failed to initialize.

       3      URL malformed. The syntax was not correct.

       ...

       88     FTP chunk callback reported error

       89     No connection available, the session will be queued

       90     SSL public key does not matched pinned public key

       91     Invalid SSL certificate status.

       92     Stream error in HTTP/2 framing layer.

...그래서 사용된 스크립트는 무엇이 잘못되었는지 curl확인 $?하고 문제에 따라 다르게 대응할 수 있습니다.

답변2

$0스크립트를 실행하는 데 사용하는 이름입니다. $1, $2등은 스크립트를 실행할 때 전달한 명령줄 인수의 값을 보유하는 스크립트의 위치 매개변수입니다.

처럼고든 데이비슨이 말했다., 책의 저자는 달리기가 ./test Linux인쇄될 것이라고 말하려고 했을 것입니다 Hello Linux. 그렇게 하면 ./test특수 매개변수로 들어가고 0, Linux첫 번째 위치 매개변수로 들어갑니다 1. 스크립트는 $1변수와 마찬가지로 첫 번째 위치 매개변수 앞에 달러 기호( )를 붙여 확장합니다 . 대신 을 실행했다면 ./test Hello Linux for Human Beings스크립트에서 , , , 및 으로 $1확장됩니다 .Linux$2for$3Human$4Beings

이를 시험해 보기 위해 간단한 스크립트를 작성할 수 있습니다.

#!/bin/bash

echo "\$0 expands to '$0'."
echo "\$1 expands to '$1'."
echo "\$2 expands to '$2'."
echo "\$3 expands to '$3'."

(원하는 만큼 진행하세요. 보다 높은 위치 매개변수의 경우 매개변수 확장 형식을 9사용하세요 . 예를 들어 을 써서 확장하세요 . 많은 위치 매개변수를 사용하는 스크립트에서는 반복을 피하기 위해 특수 매개변수를 자주 사용하지만, 원한다면 지금은 무시하세요.)${ }10${10}@

이를 파일에 저장하고 파일을 실행 가능으로 표시해 보십시오. chmod +x simplewhere simple가 다른 경우 파일 이름으로 바뀌면 실행하여 수행할 수 있습니다. 그런 다음 ./simple, ./simple foo, ./simple foo bar등과 같은 명령을 사용하여 실행할 수 있습니다 .

3개 미만의 명령줄 인수가 전달되면 전달되지 않은 인수에 해당하는 위치 매개변수가 빈 문자열로 확장됩니다. 정의되지 않은 쉘 매개변수를 확장하려고 하면 이런 일이 발생합니다. 또한 더 많은 명령줄 인수가 전달되면 세 번째 이후의 인수는 사용되지 않는다는 점을 알 수 있습니다. 스크립트가 이를 전혀 참조하지 않기 때문에 아마도 여러분이 예상한 것일 것입니다.

이제 실행해 보세요 ./simple *. 쉘은 *으로 시작하는 파일 이름을 제외하고 현재 디렉토리의 모든 파일 이름으로 확장되므로 .그 중 3개가 처음 3개의 위치 매개변수로 표시됩니다(또는 그다지 많지 않은 경우 더 적은 수). ../simple {5..10}

공백이 포함된 명령줄 인수를 따옴표로 묶어 전달할 수 있습니다. 예를 들어, 시도해 보세요 ./simple 'foo bar' baz. 이 시간뿐만 아니라 이 시간 $1까지 확장 됩니다 .foo barfoo

쉘이 수행하기 때문에다양한 확장, 명령에 전달하는 명령줄 인수의 개수가 항상 명확하지는 않습니다. 각 인수가 무엇인지 확인하는 쉬운 방법은 명령을 printf '[%s]\n'. 예를 들어:

$ printf '[%s]\n' f*
[fonts]
[fstab]
[fuse.conf]
[fwupd]
$ printf '[%s]\n' {1,3}{a..c}
[1a]
[1b]
[1c]
[3a]
[3b]
[3c]

최근에야 쉘 스크립팅을 시작했으므로배쉬 참조 매뉴얼어려울 수도 있고, 처음부터 끝까지 읽고 싶지 않을 수도 있습니다. 하지만 자신을 완전 초보자라고 생각하더라도 귀중한 자료라고 생각합니다. 다음 섹션을 찾을 수 있습니다.쉘 매개변수이미 알고 있는 쉘 변수로 시작하여 다음과 같은 특수 매개변수로 이동하기 때문에 유용 ?합니다 $?. 특히 입문 수준에서 Bash에 대한 일반적인 학습을 위해서는 다음을 권장합니다.이 페이지들, 포함배쉬가이드.

답변3

당신이 알아야 할 좋은 책 중 하나는 No Starch Press에서 출판되었으며 다음 사이트에서 무료 PDF로 제공되는 William Shotts의 "The Linux Command Line"입니다.작가의 웹사이트.

$1모든 셸 스크립트에는 일반적으로 , 등 으로 참조되는 번호가 매겨진 변수 모음이 있습니다. $2이는 명령줄 인수로 더 일반적으로 알려진 "위치 매개변수"입니다. 이를 1, 등이라는 이름의 변수로 생각할 수 있으며 해당 값을 얻으려면 , 등을 2사용합니다 . 명령줄을 통해 이름이 지정된 스크립트를 호출하면 세 개의 변수에 저장된 세 개의 인수를 얻게 됩니다 . 그리고 . 이러한 변수에 할당할 수는 없지만(그룹 제외) 해당 값을 검사하고 사용할 수 있습니다. 예를 들어 스크립트의 첫 번째 인수를 인쇄합니다.$1$2my_script./my_script a b c$1$2$3echo "$1"

$0좀 특이한데요; 실행 중인 스크립트가 호출된 이름입니다. 위의 경우 값은 입니다 ./my_script. 다시 말하지만, 값을 볼 수는 있지만 변경할 수는 없습니다.

$?방금 실행한 명령의 "종료 상태"입니다. 명령이 성공하면 종료 상태는 다음이 되고 0, 그렇지 않으면 작은 양의 정수가 됩니다. 0과 비교하여 $?이전 명령이 성공했는지 실패했는지 확인할 수 있습니다. 예를 들어, 다음 두 명령줄은 grep명령을 실행한 다음 실패 <1>했기 때문에 에코를 표시하고 (실패했음을 나타냄) grep상태로 종료됩니다 .1

grep blarg /etc/passwd
echo "<$?>"

종료 상태는 다음과 같은 간단한 스크립트를 작성하는 데 유용합니다.

#!/bin/bash
# grep_pw: grep for a pattern in /etc/passwd
grep "$1" /etc/passwd
if [[ $? = 0 ]] ;then
  echo "Found it"
  exit 0
else
  echo "Unable to find the pattern '$1' in /etc/passwd"
  exit 1
fi

해당 텍스트를 이라는 파일에 넣고 grep_pw로 실행 가능하도록 변경한 chmod 700 grep_pw다음 like를 호출하여 문자열이 포함된 ./grep_pw nologin줄을 찾습니다 ./etc/passwdnologin

쉘에 대해 처음 배웠을 때 쉘이 명령줄을 구문 분석하는 방법과 결과적으로 어떤 명령줄 인수가 스크립트에 전달되는지 이해하는 데 다음 스크립트가 매우 중요하다는 것을 알았습니다.

#!/bin/bash
# echoargs: print all the arguments
counter=1
for a in "$@" ;do
   echo "arg $counter=<$a>"
   let counter=counter+1
done

해당 내용을 이라는 파일에 넣고 echoargs실행 가능하도록 변경한 후 chmod 700 echoargs다음과 같이 호출합니다 ./echoargs a "b c" d.

관련 정보