다음과 같은 스크립트가 있습니다.
../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
스크립트 상단 근처에 추가되었습니다.
이제 실제 스크립트를 제공했으므로 다른 답변이 필요합니다. 스크립트의 문제점 01
은 dummy.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인지 확인하기 위해 추가할 수 있습니다.