file1="/scratch/abc/osx.xrts"
와 같은 두 개의 파일이 있습니다 file2="/scratch/unzip/abc/osx.xrts"
.
diff
줄 끝을 무시하고 명령을 실행하고 있습니다 . 명령과 코드는 다음과 같습니다.
diff --strip-trailing-cr file1 file2 > /dev/null
if [ $? -eq 0 ]; then
echo "no diff"
elif if [ $? -eq 1 ]; then
echo "there is diff"
else
echo "something is wrong"
fi
관찰 결과
이렇게 하면 내용 file1
과 file2
내용이 동일하다면 "차이 없음"이라는 결과가 나오며 이는 맞습니다. 그러나 문제는 내용 file1
과 내용 사이에 약간의 차이가 있을 때 발생합니다. file2
이 경우 diff
위에서 언급한 대로 명령을 실행하고 차이점을 인쇄한 후 종료됩니다. if-else 부분에는 전혀 들어 가지 않습니다.
for
많은 파일을 비교해야 하기 때문에 이 코드를 루프(여기에는 표시되지 않음)로 실행하고 있습니다 . 그러나 내 스크립트는 차이점을 인쇄하여 차이점이 있는 첫 번째 파일 쌍을 찾는 즉시 종료되며 if-else 부분에는 전혀 도달하지 않습니다. 무엇이 잘못되었는지 모르겠습니다. 어떤 도움이라도 대단히 감사하겠습니다.
내가 예상하는 결과
파일 간에 차이가 있는 경우 차이점을 인쇄하면 안 됩니다. 대신 해당 섹션으로 이동하여 elif if [ $? -eq 1 ]; then
"차이가 있습니다"를 인쇄한 다음 for
다른 파일을 비교하여 루프를 계속해야 합니다.
답변1
사소한 인쇄상의 오류를 수정한 후 코드는 다음과 같습니다.
(1) diff --strip-trailing-cr "$file1" "$file2" > /dev/null
(2) if [ $? -eq 0 ]; then
(3) echo "no diff"
(4) elif [ $? -eq 1 ]; then
(5) echo "there is diff"
(6) else
(7) echo "something is wrong"
(8) fi
(물론 위 이미지의 줄 번호는 설명을 위한 것이며 스크립트의 일부가 아닙니다.) 여기에는 아무도 지적하지 않은 미묘한 버그가 있습니다. 종료 상태가 무엇이든 diff
그 echo "something is wrong"
부분은 절대 그렇지 않습니다. 도달했다. diff
명령을 , , 등 (exit "$1")
의 숫자로 대체한 다음 인수로 전달하여 이를 쉽게 테스트 할 수 있습니다 .0
1
2
3
문제는 이것이 $?
휘발성 변수라는 것입니다. 물론 2행은 diff
1행( ) 명령의 종료상태이다. 그러나 4번째 줄은
$?
2번째 줄(test) 명령의 종료 상태입니다 [ $? -eq 0 ]
. 종료 상태가 diff
0이 아닌 경우 [ $? -eq 0 ]
테스트는 $?
1로 설정되므로언제나there is diff
소식을 받았습니다 .
이 문제를 처리하는 방법에는 여러 가지가 있습니다. 하나는 종료 상태를 diff
안정적인 변수에 저장하는 것입니다.
diff --strip-trailing-cr "$file1" "$file2" > /dev/null
diff_exit_status=$?
if [ "$diff_exit_status" -eq 0 ]; then
echo "no diff"
elif [ "$diff_exit_status" -eq 1 ]; then
echo "there is diff"
else
echo "something is wrong"
fi
물론 더 짧은 변수 이름을 사용해도 됩니다.
두 번째는 case
다음 문을 사용하는 것입니다.
diff --strip-trailing-cr "$file1" "$file2" > /dev/null
case "$?" in
(0)
echo "no diff"
;;
(1)
echo "there is diff"
;;
(*)
echo "something is wrong"
esac
답변2
file1
및 가 존재하고 동일한 경우 file2
코드 조각(표시됨)에서 구문 오류가 생성됩니다 unexpected end of file
. 이는 if
쉘이 일치하는 문을 발견하는 종료되지 않은 문으로 인해 발생합니다 fi
. 이는 elif if
대신 has 에 의해 발생 합니다 elif
. 코드의 나머지 부분에 다른 버그가 없다면 보고된 문제가 해결될 것입니다.
또한 두 개의 별도 문에서 명령을 실행하고 종료 상태를 확인하는 대신 명령의 종료 코드를 한 줄에서 직접 확인할 수 있습니다.
if diff --strip-trailing-cr file1 file2 > /dev/null; then
echo "no diff"
elif [ $? -eq 1 ]; then
echo "there is diff"
else
echo "something is wrong"
fi
그건 그렇고, 쉘 스크립트를 작성할 때 이를 확인하는 것은 정말 유용합니다.ShellCheck – 쉘 스크립트 분석 도구.