존재하다다루기 힘든
echo 'a string' > test.txt
echo $?
0
그리고
[[ $(echo 'a string') ]]
echo $?
0
하지만
[[ $(echo 'a string' > test.txt) ]]
echo $?
1
다른 예시
curl -so 'curl-8.2.1.tar.gz' https://curl.se/download/curl-8.2.1.tar.gz
echo $?
0
또는
[[ $(curl -so 'curl-8.2.1.tar.gz' https://curl.se/download/curl-8.2.1.tar.gz) ]]
echo $?
1
내 질문:
- 출력 리디렉션 때문인가요? 그렇지 않다면 그 이유는 무엇입니까?
- 명령 실행이 성공했습니다.
a string
나타나고test.txt
컬이 내가 지정한 출력 파일에 파일을 다운로드합니다. 평가 결과는 왜 나타납니까false
? - 스크립트에서 이를 처리할 수 있는 합리적인 방법이 있습니까? 특정 명령을 실행하고 싶다고 가정해 보겠습니다. 이전 명령이 성공적으로 실행되었지만
false
여전히 반환되는 경우 어떻게 실행해야 합니까? 해당 줄이 나타나는지 또는 파일이 다운로드되었는지 확인하기 위해 두 번째 검사를 추가할 수 있지만 처음에 명령이 성공적으로 실행되었는지 평가할 필요는 없습니다.
추가 완전성 예(가독성 대 "정확성"?):
if ( $(echo 'a string' > text.txt) ); then echo yes; else echo no;fi
yes
if (( $(echo 'a string' > text.txt) )); then echo yes; else echo no;fi
no
if $(echo 'a string' > text.txt); then echo yes; else echo no;fi
yes
if echo 'a string' > text.txt; then echo yes; else echo no;fi
yes
답변1
$?
내부에쉘에 의해 설정된 매개변수man 부분 zshparam
, 즉 info zsh 'Parameters Set By The Shell'
여러분이 보게 될 것은 $?
마지막 명령에 의해 반환된 종료 상태입니다.
$(...)
사람 에서는 zshexpn
다음 info zsh 'Command Substitution'
을 볼 수 있습니다.
명령 대체
'$(...)'
괄호로 묶이고 앞에 달러 기호(예: )가 있거나 악센트로 인용된 명령(예: )은...
후행 개행 문자가 제거된 표준 출력으로 대체됩니다.
예를 들어 표현식은 후행 개행 문자가 제거된 $(echo 'a string')
명령( )의 출력으로 대체되어 가 됩니다 . 그러나 내부 명령은 표준 출력으로 출력을 생성하지 않으므로 표현식의 결과는 빈 문자열입니다.a string<newline>
a string
$(echo 'a string' > test.txt)
[[ ... ]]
zshmisc
또는 맨 페이지에 info zsh 'Conditional Expressions'
다음이 표시됩니다.
조건식
조건식은 복합 명령과 함께 사용되어
[[
파일 속성을 테스트하고 문자열을 비교합니다. 각 표현식은 다음 단항 또는 이진 표현식 중 하나 이상으로 구성될 수 있습니다.
[...]
호환성을 위해 구문상 중요하지 않은 인수(일반적으로 변수)가 있는 경우 조건은 다음과 같이 처리됩니다. 식이 0이 아닌 문자열로 확장되는지 여부를 테스트합니다.
이제 예를 들어보자
따라서 다음 줄에서 명령의 출력 $( ... )
은 string a string<newline>
이므로 자체 확장자는 길이가 0이 아닌 문자열인 이므로 $(...)
계산 은 true(0 종료 상태)를 반환합니다.a string
[[ ... ]]
[[ $(echo 'a string') ]]
그러나 다음 명령에서는 리디렉션했기 때문에 확장은 $( ... )
길이가 0인 문자열이 되고 [[ ... ]]
계산은 false(0이 아닌 숫자인 종료 상태 1)를 반환합니다.
[[ $(echo 'a string' > test.txt) ]]
마찬가지로 다음 명령의 종료 상태는 curl
이 명령의 종료 상태입니다.
curl -so 'curl-8.2.1.tar.gz' https://curl.se/download/curl-8.2.1.tar.gz
will 맨페이지 curl
에서는 0이 아닌(실패) 종료 상태를 반환하는 조건을 설명합니다.
그러나 다음 예에서 종료 상태는 curl
명령에 출력이 있는지(성공) 또는 출력이 없는지(실패)에 따라 달라집니다.
[[ $(curl -so 'curl-8.2.1.tar.gz' https://curl.se/download/curl-8.2.1.tar.gz) ]]
(( ... ))
여기서 멈추겠습니다. 하지만 설명서를 계속 읽어도 됩니다.산술 평가사람의 일부 zshmisc
(또는 info zsh 'Arithmetic Evaluation'
)
답변2
[[ ... ]]
성공적인 명령 실행이 명령의 출력 결과가 0이 아닌 문자열이 되는 방식으로 이해되지 않는 한, using은 성공적인 명령 실행을 평가하는 데 적합하지 않다는 결론을 내립니다 . zsh 스크립트에서 확인하는 경우 올바른 방법은 다음과 같습니다.
if command; then ...; [else ...;] fi
(muru의 설명에 설명된 대로 사용됨)- 명령을 단독으로 실행하고
$?
나중에 종료 코드를 확인하십시오. 및/또는 - 예를 들어 생성된 파일의 내용을 검사하여 명령의 실제 출력을 확인합니다.