949

パッケージが Debian アーカイブ (.deb) ファイルから解凍される前に、スクリプトが実行するこのpreinstファイルの内容を調査しています。

スクリプトには次のコードがあります。

#!/bin/bash
set -e
# Automatically added by dh_installinit
if [ "$1" = install ]; then
   if [ -d /usr/share/MyApplicationName ]; then
     echo "MyApplicationName is just installed"
     return 1
   fi
   rm -Rf $HOME/.config/nautilus-actions/nautilus-actions.conf
   rm -Rf $HOME/.local/share/file-manager/actions/*
fi
# End automatically added section

私の最初のクエリは、次の行に関するものです。

set -e

スクリプトの残りの部分は非常に単純だと思います。Debian/Ubuntu パッケージ マネージャーがインストール操作を実行しているかどうかをチェックします。そうである場合、アプリケーションがシステムにインストールされたばかりかどうかを確認します。存在する場合、スクリプトは「MyApplicationName is just installed」というメッセージを出力して終了します (return 1つまり、「エラー」で終了しますよね?)。

ユーザーが Debian/Ubuntu パッケージ システムに私のパッケージをインストールするように要求している場合、スクリプトは 2 つのディレクトリも削除します。

これは正しいですか、それとも何か不足していますか?

4

9 に答える 9

88

が原因で中止されたスクリプトの終了ステータスが何であるかを把握しようとしているときに、この投稿を見つけましたset -e。答えは私には明らかではありませんでした。したがって、この答え。基本的にset -e、コマンド (例: シェル スクリプト) の実行を中止し、失敗したコマンドの終了ステータス コードを返します (つまり、外側のスクリプトではなく、内側のスクリプト)

たとえば、次のシェル スクリプトがあるとしますouter-test.sh

#!/bin/sh
set -e
./inner-test.sh
exit 62;

コードinner-test.shは次のとおりです。

#!/bin/sh
exit 26;

コマンド ラインから実行するouter-script.shと、外側のスクリプトは内側のスクリプトの終了コードで終了します。

$ ./outer-test.sh
$ echo $?
26
于 2016-08-05T22:54:34.417 に答える
67

bash - The Set Builtinマニュアルによると、/が設定されている場合-e、単一の単純なコマンドリスト、または複合コマンドで構成されるパイプラインがゼロ以外のステータスを返すerrexitと、シェルはすぐに終了します。

デフォルトでは、パイプラインの終了ステータスは、pipefailオプションが有効になっていない限り、パイプラインの最後のコマンドの終了ステータスです (デフォルトでは無効になっています)。

その場合、最後の (右端の) コマンドのパイプラインの戻りステータスは、ゼロ以外のステータスで終了します。すべてのコマンドが正常に終了した場合はゼロです。

終了時に何かを実行したい場合は、次のように定義してみてくださいtrap

trap onexit EXIT

以下のように、終了時に何かを行う関数はどこにonexitありますか。これは単純なスタック トレースを出力しています。

onexit(){ while caller $((n++)); do :; done; }

代わりに ERR をトラップする同様のオプション-E/があります。errtrace

trap onerr ERR

ゼロ ステータスの例:

$ true; echo $?
0

ゼロ以外のステータスの例:

$ false; echo $?
1

否定ステータスの例:

$ ! false; echo $?
0
$ false || true; echo $?
0

pipefail無効にしてテストします。

$ bash -c 'set +o pipefail -e; true | true | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; false | false | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; true | true | false; echo success'; echo $?
1

pipefail有効にしてテストします。

$ bash -c 'set -o pipefail -e; true | false | true; echo success'; echo $?
1
于 2015-12-20T13:31:37.337 に答える
1
cat a.sh
#! /bin/bash

#going forward report subshell or command exit value if errors
#set -e
(cat b.txt)
echo "hi"

./a.sh; echo $?
cat: b.txt: No such file or directory
hi
0

set -e をコメントアウトすると、echo "hi" 終了ステータスが報告され、hi が出力されることがわかります。

cat a.sh
#! /bin/bash

#going forward report subshell or command exit value if errors
set -e
(cat b.txt)
echo "hi"

./a.sh; echo $?
cat: b.txt: No such file or directory
1

代わりに b.txt エラーが報告され、hi が出力されていないことがわかります。

したがって、シェルスクリプトのデフォルトの動作は、コマンドエラーを無視して処理を続行し、最後のコマンドの終了ステータスを報告することです。エラーで終了してそのステータスを報告したい場合は、 -e オプションを使用できます。

于 2020-10-11T06:30:18.287 に答える