スクリプトのコマンドがゼロ以外のコードを返すと失敗します。

スクリプトのコマンドがゼロ以外のコードを返すと失敗します。

次のスクリプトがあります。

../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、、、)の一部である場合は終了しないでくださいwhileuntil
  • 通常のコマンドが失敗した場合、またはパイプまたはリストの最後のコマンドが失敗した場合は終了します。
  • 合成の最終結果が次のような場合、または&&失敗||した場合は終了します。

失敗する可能性のあるコマンドがありますが、終了ステータスを無視したい場合は、結果の組み合わせが|| true常に真であることを確認するために追加できます。

関連情報