bash 명령 대체 출력이 이스케이프되는 것을 방지하는 방법은 무엇입니까?

bash 명령 대체 출력이 이스케이프되는 것을 방지하는 방법은 무엇입니까?

bash 스크립트에서 명령 대체를 사용하여 다음과 같이 변수를 기반으로 리디렉션 기호를 출력하려고 합니다.

IS_VERBOSE=false
curl $BLAH $( $IS_VERBOSE && echo '-i' || echo '> /dev/null' )

즉, 장황한 경우 -i스위치를 추가하고, 그렇지 않으면 표준 출력에서 ​​모든 것을 삭제합니다. 문제는 IS_VERBOSE거짓일 때 내 명령이

curl $BLAH \> /dev/null

보다 일반적으로 명령 대체는 문자 > >> & | # $및 기타 문자를 이스케이프합니다. 명령 대체를 사용하여 이스케이프 없이 이러한 기호를 출력하려면 어떻게 해야 합니까?

답변1

대체가 발생한 후에는(POSIX에서 ">" 앞의 왼쪽만 대상으로 할 수 있음) ">"가 있는지 더 이상 평가되지 않으므로 원하는 접근 방식이 작동하지 않습니다. .

POSIX 준수에 관심이 없다면(결국 "bash"로 태그 지정함) 오른쪽을 동적으로 설정하여 해결책을 찾을 수 있지만 개인적으로는 완전히 다른 접근 방식을 취하겠습니다. 아래에서 자세히 설명합니다. 사용자 정의 파일 설명자를 기반으로 상세/자동 모드를 활성화합니다.https://stackoverflow.com/a/20942015/2261442.

게시물에서 발췌한 코드는 다음과 같은 모습을 보여줍니다.

# Some confirmations:
printf "%s\n" "This message is seen at verbosity level 3 and above." >&3
printf "%s\n" "This message is seen at verbosity level 4 and above." >&4
printf "%s\n" "This message is seen at verbosity level 5 and above." >&5

답변2

나는 이것이 당신의 탈출 문제를 해결하지 못한다는 것을 알고 있습니다(가능한지 아직 확실하지 않습니다).남자 곱슬, 이는 당신이 원하는 것을 달성할 것입니다:

BLAH=localhost

IS_VERBOSE=true
OPTIONS="-o /dev/null"
$IS_VERBOSE && OPTIONS=""

curl $BLAH -s $OPTIONS
    <html>
    <p>hi</p>
    </html>

IS_VERBOSE=false
OPTIONS="-o /dev/null"
$IS_VERBOSE && OPTIONS="-i"

curl $BLAH -s $OPTIONS

후자는 아무것도 출력하지 않습니다. 그리고 다른 쉘(bash, sh 등)에 대한 종속성이 적어서 이식성이 더 좋습니다.

답변3

Bash 매뉴얼에 따르면 쉘 확장 순서는 다음과 같습니다.중괄호 확장, 물결표 확장, 매개변수 및 변수 확장, 명령 대체, 산술 확장, 토큰화 및 경로 이름 확장. 또한 명령이 실행되기 전, 즉 쉘 확장 후에 리디렉션이 발생한다고 명시되어 있습니다. 따라서 다음과 같은 명령이 의미가 있습니다.

redir='>'
echo value $redir file

그리고

echo value $(echo '>') file

출시 예정파일에문서.

불행하게도 명령줄이 먼저 구문 분석되고 리디렉션 토큰이오직이 단계에서 결정되었습니다. 나중에 명령을 실행하기 전에 이러한 토큰을 기반으로 리디렉션이 수행됩니다.

eval curl $BLAH $( $IS_VERBOSE && echo '-i' || echo '> /dev/null' )

이는 명령을 재분석하여 리디렉션을 식별하는 방식으로 작동하지만 사용하기가 약간 까다롭고 예기치 않은 동작이 발생할 수 있는 셸 확장도 수행합니다.

노트:>$varBash에는 합계에 대한 특별한 처리가 있습니다.>&$var

관련 정보