다중 값 종료 상태 테스트(성공 또는 실패뿐만 아니라)

다중 값 종료 상태 테스트(성공 또는 실패뿐만 아니라)

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

관찰 결과

이렇게 하면 내용 file1file2내용이 동일하다면 "차이 없음"이라는 결과가 나오며 이는 맞습니다. 그러나 문제는 내용 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") 의 숫자로 대체한 다음 인수로 전달하여 이를 쉽게 테스트 할 수 있습니다 .0123

문제는 이것이 $?휘발성 변수라는 것입니다. 물론 2행은 diff1행( ) 명령의 종료상태이다. 그러나 4번째 줄은 $?2번째 줄(test) 명령의 종료 상태입니다 [ $? -eq 0 ]. 종료 상태가 diff0이 아닌 경우 [ $? -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 – 쉘 스크립트 분석 도구.

관련 정보