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' )
이는 명령을 재분석하여 리디렉션을 식별하는 방식으로 작동하지만 사용하기가 약간 까다롭고 예기치 않은 동작이 발생할 수 있는 셸 확장도 수행합니다.
노트:>$var
Bash에는 합계에 대한 특별한 처리가 있습니다.>&$var