"printf--"를 사용하는 것이 권장되는 이유"대신 "에코? " [복사]

"printf--"를 사용하는 것이 권장되는 이유"대신 "에코? " [복사]

내부에헤비히트 트랩"Greg's Wiki"에서 다음 인용문을 발견했습니다.

사실 echo여기서 이 명령을 사용하는 것은 절대적으로 안전하지 않습니다. -n예를 들어, 변수에 포함된 경우 echo인쇄할 데이터가 아닌 옵션으로 간주됩니다. 변수 값을 인쇄하는 절대적으로 신뢰할 수 있는 유일한 방법은 다음을 사용하는 것입니다 printf.

printf "%s\n" "$foo"

하지만 내가 입력할 때:

var="-n Hello"
echo "$var"

잘 작동하고 옵션으로 설명되지 않는데 , 내가 인용한 출처에서 절대적으로 안전하려면 -n이 기능을 사용해야 한다고 말하는 이유를 이해할 수 없습니다 .printf

답변1

귀하의 예에서는 "우연히" 잘 작동합니다. 그 이유는 이것이다

  • 매개변수를 하나만 제공했습니다 echo.
  • 제안된 대로 변수를 참조했습니다.

즉 , "단어" 사이의 공백을 포함하여 echo문자열만 명령줄 인수로 간주됩니다 . -n Hello이제 echo(글쎄, 일부 s)는 옵션을 인식하지만 문자열은 echo인식하지 않도록 프로그래밍되어 있으므로 옵션이라고 가정합니다.-n-n<space>Hello피연산자- 즉, "있는 그대로" 인쇄하려는 문자열입니다(아마도 \시퀀스가 ​​확장된 상태에서).

사용한 적이 있는 경우

echo $var

따옴표가 없고 기본값이 이면 $IFS공백 $var으로 분할되어 다음과 echo같이 표시됩니다.논쟁: -n-옵션으로 해석됩니다- 그리고 Hello.

이것은 의미한다이 경우, 쉘 변수를 올바르게 인용하는 것은 echo피연산자가 옵션으로 해석되는 상황이 부주의하게 발생하는 것을 방지하는 해결 방법입니다.

하지만:

  1. 링크된 소스의 예는 "전역 확장"( )을 통해 파일 목록을 인쇄하는 것입니다 *.zip. 여기서 변수는~ 해야 하다따옴표 없이 사용되므로 이 보호 기능을 항상 사용할 수 있는 것은 아닙니다.

  2. 참조 변수는 다음 상황에서만 유용합니다.분사echo옵션 매개변수가 표시 됩니다.. 인쇄하려는 매개변수가 -n처음부터 단일 매개변수인 경우 인용은 도움이 되지 않습니다.

    예를 들어, print 에 대한 문자열 배열을 수집했고 echo문자열 중 하나가 다음에 대한 옵션 인수이기도 한 상황을 생각해 보세요 echo.

    arguments=( "-n" "Hello" )
    

    그런 다음 변수를 올바르게 참조하더라도

    echo "${arguments[@]}"
    

    첫 번째 토큰은 echo여전히 -n​​피연산자가 아닌 옵션으로 간주됩니다. 여러 변수를 인수로 전달 echo하고 첫 번째 변수가 or 인 경우에도 마찬가지입니다 -n. 여기서도 변수를 인용하는 것은 도움이 되지 않습니다.

  3. 일반적으로 프로그램이 다음 형식의 매개변수를 허용하는 경우에는 인용조차 도움이 되지 않습니다.-oValue.

    가상의 상황에서 my_formula_renderer수학 공식을 형식화하고 선택적 인수를 허용하는 프로그램을 사용하십시오. 그런 다음 다음과 같은 수식을 조판한다고 가정해 보겠습니다.-sfontsize-sqrt(a^2 + b^2)

    ./my_formula_renderer "-sqrt(a^2+b^2)"
    

    프로그램에 종료 옵션 구문 분석 지정자가 없으면 위 수식의 기본 글꼴 크기를 사용하는 대신 --글꼴 크기 조판 "없음"을 사용하려고 한다고 가정합니다 .qrt(a^2+b^2)

    ; -s와 같은 다른 수식 요소 사이에 명시적인 공백이 있는 경우 에도 도움이 되지 않습니다. 선행 공백이 있는 "글꼴 크기" "-s +2t +u^2"로 잘못 해석했을 수도 있습니다 (참조+2t +u^2예를 들어 이 질문이것이 문제가 됩니다.)

  4. 프로그램이 단일 문자 옵션의 "클러스터링"을 허용하는 경우에도 마찬가지입니다.

    예를 들어 @Stéphane Chazelas가 지적했듯이 echo문자열은 options 및 의 연결로 해석될 수 있으므로 해당 문자열 -neEenennne을 인쇄하려고 하면 예기치 않은 방식으로 실패하거나 동작할 수 있습니다.-n-e-Eecho

  5. 옵션 처리 외에도 echo( 일부 버전에서는 기본적으로 옵션이 활성화된 경우를 echo포함하여 일부 ) 등 이 개행, 백슬래시, 백스페이스 문자로 확장 됩니다.bashxpg_echo\n\\\b백슬래시가 포함될 수 있는 축어적 문자열을 출력하는 데 사용할 수 없습니다..

TL/DR

핵심은 당신이 인용한 출처에 '절대'라는 단어가 있고, echo그것이 구체적으로 가리키는 사실이다. 대부분의 경우 echo괜찮을 것입니다. 그러나 맹목적으로 의존하기 시작하면 (조만간) 어떤 일이 일어나 echo거나 실제로는 더 중요한 또 다른 프로그램이 될 것입니다."피연산자" 매개변수로 의도한 것을 실수로 "옵션" 매개변수로 잘못 해석함, 일반적으로 쉘 변수로 전달할 때.

관련 정보