"대시"에서 실행할 때 printf 바이트 형식 지정이 실패하는 이유는 무엇입니까?

"대시"에서 실행할 때 printf 바이트 형식 지정이 실패하는 이유는 무엇입니까?

0에 대한 ASCII 16진수 코드는 0x30입니다. 따라서 을 수행하여 0을 인쇄할 수 printf '\x30'있으며 0이 인쇄됩니다.

이것을 myScript.sh라는 쉘 스크립트에 넣은 다음 실행하면 ./myScript.sh0도 인쇄됩니다.

sh -c printf '\x30'그러나 or 을 수행하면 sh myScript.sh단일 바이트로 해석되는 대신 리터럴 문자 "\x30"을 얻게 됩니다.

왜 그런 겁니까?

(이 동작은 여러 컴퓨터에서 관찰되었으며, 모두 bash를 실행하고 있다고 생각합니다.)

답변1

printf일부 쉘의 구현 ( bash적어도 에뮬레이션 모드에서도 ksh) 은 이를 16진수로 이해합니다 . 그러나 이것은 사실이다zshsh\xHHHHprintf표준.

POSIX 표준에는 1자리, 2자리 또는 3자리 숫자 의 printfID가 필요합니다.\oooooo8진수형식 매개변수의 숫자와 형식 지시문 \0ooo에 사용되는 %b인수의 숫자 ( echo동작과 일치시키기 위해).

/bin/sh시스템에 표시되는 쉘은 와 함께 사용될 때 8진수(모든 표준 쉘과 마찬가지로)를 이해하지만 16진수는 이해하지 dash못합니다 .yashprintf

16진수 30을 8진수로 변환하면 60이므로

$ sh -c 'printf "%b\n" "$1"' sh '\060'
0

또는 8진수를 매개변수로 전달하고 싶지 않지만 이를 정적 리터럴로 사용하려는 경우:

$ sh -c 'printf "\60\n"'
0

(귀하의 질문에 있는 진술의 차이점에 유의하십시오 sh -c. 전체 진술(인수 포함)은 유틸리티 option 의 options 매개변수로 제공된 문자열의 일부입니다 printf. 귀하의 질문에 있는 내용은 단순한 오타라고 가정합니다.)sh-c

스크립트가 문자를 성공적으로 인쇄하는 이유 는 0스크립트 에 쉘 실행 파일을 가리키는 #!-line이 있거나bash아니요그러한 줄은 전혀 없으며 대신 스크립트는 대화형 쉘에서 실행됩니다 bash. bash라인 없이 쉘 스크립트를 실행하는 경우 #!쉘을 사용하여 bash이를 실행합니다(참조:Shebang 없이 스크립트를 실행하는 쉘 인터프리터는 무엇입니까?이에 대한 자세한 내용은 자세히).

명시적 인터프리터(그림 참조)를 사용하여 스크립트를 실행하면 sh myScript.sh#!줄(있는 경우)이 무시됩니다.

답변2

내가 실행할 때

$ sh -c printf '\x30'

알겠어요

printf: usage: printf [-v var] format [arguments]

이미 귀중한 힌트를 제공하지만 printf예상되는 매개변수를 얻지 못합니다. 해결책은 명령 매개변수를 따옴표로 묶어서 명령 매개변수가 다중 매개변수가 아닌 단일 문자열인지 확인하는 것입니다. 물론 가독성을 높이기 위해 줄바꿈을 추가하는 것도 나쁘지 않습니다.

$ sh -c "printf '\x30\n'"
0

관련 정보