我有这样的脚本:
../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
您应该使脚本可执行,并让脚本本身定义用于执行它们的 shell。然后,您可以向解释器行添加标志来解决您提出的问题。
这可能会导致脚本在出现第一个错误时退出:
#!/bin/sh -e
../configure
make
make install
不幸的是,您无法以简单且独立的方式做到这一点,因为您指定了在调用脚本时要使用的解释器(shell)。
因此,您需要-e
在使用 shell 调用脚本时将标志添加到 shell,这很混乱,因为您将程序逻辑放在程序本身之外:
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。