bash -c 명령 분석

bash -c 명령 분석

Bash 맨페이지에서는 이 옵션을 다음과 같이 설명합니다 -c.

-c -c 옵션이 있는 경우 옵션이 아닌 첫 번째 인수 command_string에서 명령을 읽습니다. command_string 뒤에 인수가 있는 경우 첫 번째 인수는 $0에 할당되고 나머지 인수는 위치 인수에 할당됩니다. $0에 대한 지정은 경고 및 오류 메시지에 사용되는 쉘의 이름을 설정합니다.

위에서부터 다음 코드는 출력에서 ​​동일할 것으로 예상됩니다.

# or possibly (`bash -c date date +%z`)
$ bash -c date +%z
Wed Oct 18 10:02:47 PM UTC 2023
$ date +%z
+0000
# The first command gives the output of `date` without the format specifier.

그러나 내 bash(GNU bash, 버전 5.2.15)는 추가 명령줄 위치 인수를 평가하지 않는 것 같습니다. 옵션 뒤의 첫 번째 인수 이후의 모든 항목은 -c자동으로 삭제됩니다. 어쩌면 내가 매뉴얼 페이지를 오해했을 수도 있습니다.

bash -c문자열( )이 아닌 단어(기본 arg 벡터)로 명령에 여러 인수를 전달하려면 어떻게 해야 합니까 bash -c "date +%z"? 가능합니까?

문맥

이 질문을 하는 목적은 bash가 어떻게 명령 인수가 전달되어 execve()다른 프로그램(래퍼 쉘)의 함수 계열 중 하나를 통해 bash에 올바르게 입력될 수 있는지 이해하는 것입니다.

답변1

첫 번째 매개변수는 $0에 할당됩니다.

$0은 첫 번째 매개변수가 아니며 $1은 첫 번째 매개변수입니다. 또한 명령 문자열의 매개변수를 사용해야 합니다.

bash -c 'date "$1"' zero +%z

답변2

여기,

bash -c date +%z

-cis 다음의 첫 번째 비옵션 인수는 dateBash가 구문 분석하고 실행할 쉘 코드입니다. 그 뒤의 인수는 셸 또는 스크립트 이름 $0(여기서 +%z)에 할당되고 위치 인수 $1... $2(여기에서는 모두 설정되지 않음)에 할당됩니다.

문자열은 +%z폐기되지 않지만 명령이 사용 (또는 등) date되지 않으므로 쉘의 작동에 영향을 미치지 않습니다. 그러나 쉘이 오류 메시지를 인쇄해야 하는 경우에 사용됩니다. 예를 들어:$0$1

$ /bin/bash -c datexxx +%z
+%z: datexxx: command not found

스크립트는 명령을 찾을 수 없으므로 datexxx우리가 스크립트에 지정한 이름( +%z)이 앞에 붙은 오류 메시지를 인쇄합니다.


다음 매개변수와 셸 코드를 사용하려면 스크립트 이름이나 위치 매개변수를 사용하여 명령을 -c전달해야 합니다 . 예:$0$1

% bash -c 'echo "script name: $0", first arg: "$1"' foo bar doo
script name: foo, first arg: bar

그러나 인수 목록을 있는 그대로 다른 명령에 전달하려는 경우 ( 모든 설정에 대한 위치 인수에 대해 수행하는 "$@"것과 마찬가지로) (따옴표 포함)를 사용하여 모든 위치 인수를 고유 필드로 확장하는 것이 좋습니다 "$1" "$2" ....

따라서 (GNU 날짜가 이라고 가정 -d):

% bash -c 'date "$@"' my-inline-script +"%F %T" -d '1 Jan 2001'
2001-01-01 00:00:00

(이것은 쉘이 오류 메시지를 인쇄해야 할 때만 사용 my-inline-script됩니다 . 위의 예는 설명적인 내용을 거기에 넣는 것이 왜 의미가 있는지 보여줍니다. 그럼에도 불구하고 이전에 채워진 위치 인수 값을 $0전달해야 합니다 . )$0

답변3

매개변수는 -c문자열이어야 합니다. 나머지는 매개변수 $0, $1, ... 가 됩니다 .

예:

bash -c 'echo name=$0 params=$*' a b c

산출:name=a params=b c

여기서는 작은따옴표를 사용하는 것이 중요합니다. 현재 쉘이 $0등 의 값을 채우는 것을 허용하지 않기 때문입니다.$*

현재 쉘에서 값을 얻으려면 큰따옴표를 사용하십시오. 예를 들어:

X=42
bash -c "echo $X"

산출:42

작은따옴표와 큰따옴표를 혼합하는 것도 가능합니다. 다음 매개변수가 -c여전히 문자열인 한.

X=42
bash -c "echo $X"' 0=$0 $*' 

출력: ( 42 0=bash 여기서 $0기본값 bash)

관련 정보