bashで最後に失敗したコマンド


回答:


6

fc前のコマンドラインを取得するために使用します。これは通常、お気に入りのエディターで前のコマンドラインを編集するために使用されますが、「リスト」モードもあります。

last_command="$(fc -nl -1)"


これは悲しいことに、私が使用中の使用または機能に大きなcase文がある場合に予想されるどのように私が使用して終了:( ...非常にうまく機能していないcallerとbashのアレイBASH_LINENOBASH_SOURCEおよびFUNCNAMEスタックトレースの種類を行うこと。
phyatt

6

場合は、最後のコマンドを引数なしで実行された、それは内に保存されます$_変数。これには通常、前のコマンドの最後の引数が含まれます-引数がない場合、の値$_は最後のコマンド自体です。

別のオプションは、最後のバックグラウンドコマンドの詳細を学ぶことです。l0b0が書いたように、$!そのPIDを保持しているため、の出力を解析できますps $!(追加のフォーマットオプションを使用してps)。


2

いいえ。ただし、実行中に取得して、他のコマンド用に保存できます。

  • $0:現在のシェルスクリプトのパス。
  • $FUNCNAME:「現在の関数の名前」
  • "$@":個別に引用された現在のコマンドのすべてのパラメーター。
  • $!:「バックグラウンドで実行された最後のジョブのPID(プロセスID)。」
  • $$:「スクリプト自体のプロセスID(PID)。」

したがって、現在のスクリプトの完全なコマンドはになります"$0" "$@"。それが関数であるなら、それはそうあるべきです"$FUNCNAME" "$@"。将来の処理のために、それを配列に格納することができます。たとえば、次の場所に保存しtest.shます。

#!/usr/bin/env bash
foo()
{
    declare -a command=("$0")
    for param in "$@"
    do
        command+=("$(printf %q "$param")")
    done
    echo "${command[@]}"
}
foo "$@"

を実行すると./test.sh "first argument" "second argument"、次が返されます。

./test.sh first\ argument second\ argument

これは同等の呼び出しです。


bashにはBASH_COMMAND変数がありますが、トラップでの使用を除いて、まったく役に立たないようです。
enzotib 2011年

ご入力いただきありがとうございます。some-commandシェルスクリプトで実行すると失敗します。でゼロ以外のステータスになりますが$?、変数保持の存在に対して「いいえ」はまだ保持されsome-commandますか?
Eimantas、2011年

私の知る限り、コマンドが失敗したという唯一の事実は、シェルがそのコマンドについて保存している一連の情報を変更しません。ですから、「はい」と答えます。
rozcietrzewiacz

2

DEBUGトラップは、あなたが右のいずれかの簡単なコマンドを実行する前にコマンドを実行することができます。BASH_COMMAND変数では、実行するコマンドの文字列バージョン(単語はスペースで区切られています)を使用できます。

trap 'previous_command=$this_command; this_command=$BASH_COMMAND' DEBUG

echo "last command is $previous_command"

previous_commandコマンドを実行するたびに変更されることに注意してください。使用するために、変数に保存してください。前のコマンドの戻りステータスも知りたい場合は、両方を1つのコマンドに保存します。

cmd=$previous_command ret=$?
if [ $ret -ne 0 ]; then echo "$cmd failed with error code $ret"; fi

失敗したコマンドでのみ中止したい場合は、を使用set -eして、最初に失敗したコマンドでスクリプトを終了します。EXITトラップから最後のコマンドを表示できます。

set -e
trap 'echo "exit $? due to $previous_command"' EXIT

一部の用途で機能する可能性のある別のアプローチは、を使用set -xしてスクリプトの実行のトレースを出力し、トレースの最後の数行を調べることです。


0

set -eset -o pipefailオプションがある場合、最後に失敗したコマンドを見つけることが重要です。それ以外の場合、bashは単に理由をフィードバックせずに中止するため、これがうまく機能していることがわかりました。

#!/usr/bin/env bash
set -eu
set -o pipefail

cur_command=
first_err_command=
first_err_lineno=
# This trap is executed in exactly the same conditions in which the `set -e` results in an exit.
trap 'cur_command=$BASH_COMMAND;
      if [[ -z "$first_err_command" ]]; then
          first_err_command=$cur_command;
          first_err_lineno=$LINENO;
      fi' ERR
trap 'if [[ ! -z "$first_err_command" ]]; then
          echo "ERROR: Aborting at line: $first_err_lineno on command: $first_err_command";
      fi' EXIT

echo "The following command causes bash to abort, but it should also result in a nice message"
false
echo "This message is not expected"

上記を実行すると、以下のような出力が表示されます。

The following command causes bash to abort, but it should also result in a nice message
ERROR: Aborting at line: 22 on command: false

行番号は常に正確であるとは限りませんが、役立つように十分に近いものを提供するはずです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.