문맥:https://stackoverflow.com/a/37253784/15603477
cmd='printf "%s\n" "$(date -d "$variable" +%c)"'
echo ${variable}
반품2010-09-08 12:34:56
echo "$cmd"
반품 printf "%s\n" $(date -d "$variable")
echo "${cmd}"
반품printf "%s\n" $(date -d "$variable")
bash -c "$cmd"
그런 다음 답변에 표시된 대로 다음 명령을 실행합니다 .
Fri
Dec
24
00:00:00
IST
2021
발견된 내용은 다음과 같습니다.
- https://stackoverflow.com/questions/20858381/what-does-bash-c-do
- https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Invoking-Bash
옵션이 아닌 첫 번째 인수 command_string에서 명령을 읽고 실행한 후 종료합니다. command_string 뒤에 인수가 있는 경우 첫 번째 인수는 $0에 할당되고 나머지 인수는 위치 인수에 할당됩니다. $0에 대한 지정은 경고 및 오류 메시지에 사용되는 쉘의 이름을 설정합니다.
내 질문은 마지막 명령 bash -c "$cmd"
, 출력에 관한 것입니다.오늘(현재 2021년 12월 24일입니다.) 어디서 오셨나요?
--업데이트: 확인했습니다.https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#eval,https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Bourne-Shell-Builtins,https://man7.org/linux/man-pages/man1/bash.1.html
다음 인용문은 내가 찾은 것입니다.eval
eval [arg ...] 인수를 읽고 이를 단일 명령으로 연결합니다. 그런 다음 쉘은 명령을 읽고 실행하며 해당 종료 상태는 eval 값으로 반환됩니다. 만약에
답변1
쉘 코드는 3개의 매개변수를 사용하여 명령을 bash -c "$cmd"
실행합니다 .bash
bash
-c
$cmd
가변 내용
bash
이러한 쉘을 호출하는 것은 세 번째 인수의 코드를 해석하는 표준 방법입니다(단지 1이 아닌 모든 쉘이 이를 수행함).
$cmd
여기서는 다음과 같이 초기화된다고 말합니다 .
cmd='printf "%s\n" "$(date -d "$variable" +%c)"'
그러나 출력에는 다음 echo "$cmd"
과 같이 할당된 것으로 표시됩니다.
cmd='printf "%s\n" $(date -d "$variable" +%c)'
따라서 새 호출에 의해 해석될 쉘 코드는 다음 bash
과 같습니다.
printf "%s\n" $(date -d "$variable" +%c)
이제 bash
새로운 통역사가 시작되므로 $variable
거기에 할당되지 않습니다. 대신 bash -uc
( 와 동일 bash -o nounset -c
)을 실행하면 -c
다음을 얻게 됩니다.
bash: line 1: variable: unbound variable
이 nounset
옵션이 없으면 설정되지 않은 변수는 마치 비어 있는 것처럼 확장되므로 date
다음 인수를 사용하여 명령을 호출하십시오.
date
-d
- 공리
+%c
-d
표준 date
옵션이 아닙니다. GNU의 경우 date
입력 날짜를 지정하는 데 사용됩니다. 입력 날짜가 비어 있으면 date -d 0
또는 date -d 00:00:00
, 즉 오늘 아침 00:00:00 과 같습니다 .
이제 $(date...)
참조가 없고 목록 컨텍스트( printf
명령 인수)에 있기 때문에 분할+glob의 영향을 받습니다. 분할 부분은 공백, 탭 및 개행 문자가 포함된 bash의 기본 날짜 출력을 중단하므로 출력에서 공백으로 구분된 각 단어에 대해 생성된 별도의 인수를 $IFS
볼 수 있습니다 (와일드카드 부분은 여기서 아무 작업도 수행하지 않습니다. ) 출력에는 와일드카드 문자가 없습니다 .printf
date
date
따라서 date
다음을 출력 하면 다음 매개변수가 포함된 호출이 Fri Dec 24 00:00:00 IST 2021
발생합니다 .printf
printf
%s\n
Fri
Dec
00:00:00
IST
2021
모든 인수를 사용하기 위해 가능한 한 여러 번 형식을 printf
재사용 하고 결국 모든 인수를 별도의 줄에 인쇄합니다.%s\n
bash
이제 이 새 인스턴스를 원한다면상속하다이를 호출하는 셸 의 경우 나중에 호출하는 각 명령에 대한 환경에 이 변수를 추가 $variable
할 수 있습니다 .export
export variable
bash -c "$cmd"
( printenv variable
, perl -E 'say $ENV{variable}'
...도 볼 수 있습니다).
또는 bash
³를 한 번만 호출하려면 다음을 수행하세요.
(export variable; exec bash -c "$cmd")
또는:
variable=$variable bash -c "$cmd"
존재하다
eval "$cmd"
현재 셸에는 해석의 코드가 전달되며 $cmd
이는 호출 내에서 디스패치된 셸이므로 $variable
해당 내용에 액세스할 수 있으므로 환경으로 내보낼 필요가 없습니다.
¹ 이는 실제로 쉘 언어로 간주될 수 없는 다른 언어에 대한 일부 통역사의 경우에도 해당됩니다. python
예를 들어 일부는 다른 옵션을 사용합니다(예: sed -e 'sed code'
, perl -e 'perl code'
, php -r 'php code'
... 또는 전혀 옵션 없음) awk 'awk code'
.sed 'sed code'
² 및 $0
는 로 설정되어 bash
있으며 여기의 위치 매개변수 목록은 비어 있습니다.
bash
3 및 인스턴스가 자체적으로 실행할 명령
답변2
이 변수로 정의된 명령은 $cmd
이름이 지정된 변수를 참조합니다 $variable
. $cmd
다른 프로세스의 새 쉘 호출로 전달되는 경우 $cmd
이 변수는 실행 시 설정되지 않습니다. 따라서 날짜 가져오기 호출의 결과는 date -d "" +%c
현재 날짜를 반환한다는 것입니다.
코딩 관점에서 명령을 변수에 저장하는 것은 나쁜 습관입니다. 너~ 할 것이다조만간 당신은 인용의 악몽에 빠지게 될 것입니다. 변수를 데이터로, 함수를 코드로 사용하세요.
cmd() {
local v=$1
printf "%s\n" "$(date -d "$v" +%c)"'
}
variable="2010-09-08 12:34:56"
cmd "$variable"
마지막으로, 타당한 이유가 없는 한 변수를 사용할 때 항상 큰따옴표로 묶어야 합니다. ( echo $variable
나쁨, echo "$variable"
더 좋음, printf "%s\n" "$variable"
최고.)