次のスクリプトがあります。
../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
常に真であることを確認するために追加できます。