Linux
如果一個命令在腳本中返回非零程式碼則失敗
我有這樣的腳本:
../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。
您應該使您的腳本可執行,並讓腳本本身定義用於執行它們的 shell。然後,您可以在解釋器行中添加標誌,以解決您提出的問題。
這可能會導致腳本在第一個錯誤時退出:
#!/bin/sh -e ../configure make make install
不幸的是,您不能以簡單且獨立的方式執行此操作,因為您在呼叫腳本時指定了要使用的解釋器(shell)。
因此,您需要
-e
在使用它來呼叫腳本時將標誌添加到 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
以確保生成的複合始終為真。