스크립트의 명령이 0이 아닌 코드를 반환하면 실패합니다.

스크립트의 명령이 0이 아닌 코드를 반환하면 실패합니다.

다음과 같은 스크립트가 있습니다.

../configure
make
make install

스크립트를 실행하면 실패하더라도 항상 0을 반환합니다. 실패할 경우 하위 명령 반환 코드를 반환해야 합니다.어떻게 해야 하나요?

편집: 파일의 실제 내용:

정지시키다:

#!/bin/bash
timeout 18900 su lfs $@
EXITCODE=$?
echo $EXITCODE
#succeed on timeout
if (( $EXITCODE == 124 )) 
then
    exit 0
fi
exit $EXITCODE

01:

#!/bin/bash -e
./prepare
echo $LFS
echo $LFS_TGT
echo $PATH
echo $CONFIG_SITE
echo 'int main(){}' > dummy.c && g++ -o dummy dummy.c
if [ -x dummy ]
  then echo "g++ compilation OK";
  else echo "g++ compilation failed"; fi
rm -f dummy.c dummy

나는 그것을 다음과 같이 호출합니다: ./timeout ./01 그리고 나는 다음과 같은 결과를 얻습니다:

./1: line 7: dummy.c: Permission denied
g++ compilation failed

그리고 ./timeout 스크립트는 0을 반환합니다.

편집 2: 다른 파일에서 동일한 시간 초과 스크립트를 사용해 보았지만 실패했습니다. 11:

#!/bin/bash 
./prepare
export MAKEFLAGS='-j2'
cd $LFS/sources
tar -xvf coreutils-8.32.tar.xz
cd coreutils-8.32
case $(uname -m) in
    aarch64) patch -Np1 -i ../coreutils.patch
    ;;
    riscv64) patch -Np1 -i ../coreutils.patch
    ;;
esac
./configure --prefix=/usr                     \
            --host=$LFS_TGT                   \
            --build=$(build-aux/config.guess) \
            --enable-install-program=hostname \
            --enable-no-install-program=kill,uptime
make
make DESTDIR=$LFS install
mv -v $LFS/usr/bin/chroot                                     $LFS/usr/sbin
mkdir -pv $LFS/usr/share/man/man8
mv -v $LFS/usr/share/man/man1/chroot.1                        $LFS/usr/share/man/man8/chroot.8
sed -i 's/"1"/"8"/'                                           $LFS/usr/share/man/man8/chroot.8
rm -rf $LFS/sources/coreutils-8.32

파일이 존재하지 않기 때문에 패치가 실패하지만 스크립트는 0을 반환합니다.

답변1

스크립트를 실행 가능하게 만들고 스크립트 자체가 이를 실행하는 데 사용되는 셸을 정의하도록 해야 합니다. 그런 다음 통역사 줄에 플래그를 추가하여 요청한 문제를 해결할 수 있습니다.

이로 인해 첫 번째 오류가 발생하면 스크립트가 종료될 수 있습니다.

#!/bin/sh -e
../configure
make
make install

불행하게도 스크립트를 호출할 때 사용할 인터프리터(셸)를 지정하기 때문에 간단하고 독립적인 방법으로는 이 작업을 수행할 수 없습니다.

따라서 셸을 사용하여 스크립트를 호출할 때 셸에 플래그를 추가해야 합니다 -e. 이는 프로그램 논리를 프로그램 자체 외부에 두기 때문에 혼란스럽습니다.

sh -e somescript.sh

또는 set -e스크립트 상단 근처에 추가되었습니다.


이제 실제 스크립트를 제공했으므로 다른 답변이 필요합니다. 스크립트의 문제점 01dummy.c. 이것이 Permission denied메시지가 나타나는 원인이며 ,그러나 반드시 그런 것은 아니다후속 g++ compilation failed뉴스. 오류가 포착되지 않으며 01실제 상태에 관계없이 스크립트가 성공적으로 종료됩니다. 결과적으로 timeout성공적인 종료로 이어집니다.

문서timeout

#!/bin/sh
timeout 18900 su lfs -c "$*"
exitcode=$?
echo $exitcode

#succeed on timeout
[ $exitcode -eq 124 ] && exit 0
exit $exitcode

문서01

#!/bin/sh
./prepare
echo "$LFS"
echo "$LFS_TGT"
echo "$PATH"
echo "$CONFIG_SITE"
echo 'int main(){}' > dummy.c && g++ -o dummy dummy.c && [ -x dummy ]
exitcode=$?

if [ $exitcode -eq 0 ]
  then echo "g++ compilation OK"
  else echo "g++ compilation failed"
fi

rm -f dummy.c dummy
exit $exitcode

여기서는 사용하지 않지만 나중에 참조할 수 있도록 이 set -e옵션(활성화 방법에 관계없이)에는 특정 규칙 세트가 있습니다. 주로 그러나 배타적이지는 않지만,

  • if실패한 명령이 루프 또는 분기 조건( / elif, while, until) 의 일부인 경우 종료하지 마십시오.
  • 일반 명령이 실패하거나 파이프 또는 목록의 마지막 명령이 실패하면 종료합니다.
  • 합성의 최종 결과가 다음 과 같 &&거나 ||실패 하면 종료됩니다.

실패할 수 있는 명령이 있지만 종료 상태를 무시하려는 경우 || true결과 조합이 항상 true인지 확인하기 위해 추가할 수 있습니다.

관련 정보