첫 번째 스크립트에서 호출된 스크립트가 오류 코드와 함께 종료될 때 스크립트를 계속 실행하려면 어떻게 해야 합니까?

첫 번째 스크립트에서 호출된 스크립트가 오류 코드와 함께 종료될 때 스크립트를 계속 실행하려면 어떻게 해야 합니까?

나는 실패할 때까지 두 번째 스크립트를 반복적으로 실행하고 두 번째 스크립트의 stdout 및 stderr을 캡처하는 bash 스크립트를 작성하려고 합니다. 나는 그 과정에서 직면한 대부분의 문제를 처리하여 다음 스크립트( 라고 함)를 사용하게 되었습니다 error_checker.sh.

#!/usr/bin/env bash

i=0

while [ $? -ne 1 ]
do
i=$[$i+1]
source script.sh &> log.txt
echo "This error occurred after $i run(s)." >> log.txt
done

반복하려는 스크립트가 호출 script.sh되고 다음 코드가 있습니다.

#!/usr/bin/env bash

 n=$(( RANDOM % 100 ))

 if [[ n -eq 42 ]]; then
    echo "Something went wrong"
    >&2 echo "The error was using magic numbers"
    exit 1
 fi

 echo "Everything went according to plan"

스크립트 error_checker.sh는 실패한 실행의 stdout 및 stderr을 지정된 파일 log.txt로 출력할 수 있지만, 스크립트가 줄의 두 번째 스크립트와 함께 종료되면

source script.sh &> log.txt

따라서 파일에 추가 오류 메시지를 추가할 수 없습니다.

잠시 검색한 결과 이것이 두 번째 스크립트를 실행할 때 하위 쉘을 생성하는 것과 관련이 있을 수 있다는 것을 발견했습니다. 그러면 문제가 해결될 수 있지만 대신 그렇게 하면 전체 터미널이 ./작동 하지 않습니다. 를 입력하면 멈춥니다 .sourcesource././error_checker.sh

어떤 도움의 손길이라도 대단히 감사하겠습니다!

고쳐 쓰다: 현재 답변에 감사드립니다! 지금 내 주요 문제는 source script.sh새 쉘 프로세스 ./script.sh에서 실행하도록 변경하면 error_checker.sh전체 터미널이 정지되어 을 사용할 수 없다는 것입니다. ./이것이 바로 를 error_checker.sh사용할 때만 성공적으로 실행할 수 있는 이유입니다 source script.sh. 무슨 일인지 아이디어가 있나요?

업데이트 2: 전체 터미널이 정지된 것처럼 보였고 Ctrl+C를 눌러 프로세스를 종료해야 했지만 여전히 log.txt가 생성되는 것으로 source변경 했습니다 . ./그러나 사용 버전은 stdout 및 stderr이 using을 통해 캡처되었음을 나타내는 sourcelog.txt 말했다를 생성하는 반면 , 사용 버전은 log.txt 말했다를 생성합니다 . 무슨 일이 일어났는지 아세요?Something went wrong. The error was using magic numbers&>./Everything went according to plan. The error occurred after X run(s)

최종 업데이트: 아래 Glenn의 답변을 기반으로 코드를 편집했는데 제대로 작동합니다. while 루프의 echo 명령으로 인해 실제로 script.ph의 종료 상태를 평가할 수 없어 무한 루프가 생성되는 것 같습니다.

#!/usr/bin/env bash

i=0

while [ $? -ne 1 ]
do
((i++))
./script.sh >& log.txt
done

echo "This error occurred after $i run(s)." >> log.txt

답변1

스크립트를 받고 있으므로 exit 1다음으로 변경하십시오.return 1

script.sh를 "최상위" 스크립트로 실행하려는 경우 다음을 수행할 수 있습니다.

if (( n == 42 )); then
    if [[ "$0" == "${BASH_SOURCE[0]}" ]]; then
        # I'm the "main" script
        exit 1
    else
        # I'm being sourced from some other script
        return 1
    fi
fi

만약 너라면~ 해야 하다source(의심스럽지만 코드를 확인해야 함)를 사용하면 스크립트를 변경할 수 없으므로 하위 쉘에서 명령을 소싱해야 합니다. 이는 exit최상위 프로그램을 실행하는 현재 셸이 아닌 하위 셸에서 종료된다는 의미입니다.

i=0
#     /--------------------------------\  parentheses create a subshell
while (source script.sh >> log.txt 2>&1)
do
    ((i++))
done
echo "This error occurred after $i run(s)." >> log.txt

그러면 다음을 포함하는 로그 파일이 생성됩니다.

Everything went according to plan
...
Everything went according to plan
Something went wrong
The error was using magic numbers
This error occurred after 302 run(s).

코드에 대한 몇 가지 참고 사항:

  • $[...]문서화되지 않은 구문이므로 더 이상 사용되지 않을 수 있습니다. $((...))산술 확장 또는 산술 평가 에 사용됩니다 ((...)).
  • $?종료상태인가요더 일찍while 루프의 두 번째 반복에 대한 명령은 입니다 echo. echo표준 출력(또는 지정된 파일 설명자)을 쓸 수 없는 경우에만 0이 아닌 값이 반환되므로 무한 루프가 발생합니다.script.sh의 종료 상태를 테스트하지 않았기 때문입니다!
    • 오류 상황 후에 Ctrl+C를 누를 확률은 약 1%이므로 로그 파일에 "양호한" 메시지가 포함될 확률은 99%입니다.
  • &>관용적이지 않음: 사용되거나 >& file더 명확함 >file 2>&1.
  • "다음 이후에 오류가 발생했습니다." 메시지를 인쇄하고 싶을 가능성이 높습니다.외부회보

관련 정보