Linuxで追加のコマンドを実行した後にプロセス終了ステータスを取得する方法はありますか?

Linuxで追加のコマンドを実行した後にプロセス終了ステータスを取得する方法はありますか?

多くのコマンドを実行し、100個のコマンドの前に終了したプロセスの終了状態が必要な場合はどうなりますか?終了したすべてのプロセスにアクセスし、それに関する情報を表示できる構造、ファイルの場所、または変数はLinuxにありますか?

答え1

GNU 6.6.3以降(accton onリリース済み)を使用してBSDプロセスアカウントを有効にした場合(またはプロセスアカウントデータがシステムに保存されている場所)からこの情報を取得できます。acctlastcomm --debugdump-acct /var/log/account/pact

$ perl -e '123番出口'
$lastcomm --debug grepパール|
現在の記録:パール| v3 | 0.00 | 1000 | 0.00 |     123|pts/1 |2018年9月19日水曜日 20:21:26
$ダンプ-acct /var/log/account/pacct grep perl |
パール| v3 | 0.00 | 1000 | 0.00 |     123|pts/1 |2018年9月19日水曜日 20:21:26

終了コードと終了かどうかを取得できます(ただし、信号番号は不明です。参照)。これに対する@mosvyの答え)最後の4番目。

答え2

Debianを使用している場合は、このacctパッケージをインストールしてプロセスアカウントを有効にできますが、終了ステータスやプロセスを終了する信号などは表示または表示されませんlastcomm --debugdump-acct

このデータを取得するには、次のスクリプトを使用できます。

$ cat pacct.pl
#! /usr/bin/perl
use strict;
use Config;
printf "%-7s %6s %6s  %8s %8s  %s\n",
        'STATUS', 'UID', 'PID', 'BTIME', 'ETIME', 'COMMAND';
my @sig = split ' ', $Config{sig_name};
$/ = \64;
while(<>){
        my @f = unpack 'CCSL6fS8A*', $_;
        my ($flag, $version, $tty, $exitcode, $uid, $gid, $pid, $ppid,
                $btime, $etime, $utime, $stime, $mem, $io, $rw,
                $minflt, $majflt, $swaps, $cmd) = @f;
        my $s = $exitcode & 0x7f;
        my $status = $s ?  "SIG$sig[$s]" : $exitcode >> 8;
        printf "%-7s %6d %6d  %02d:%02d:%02d %8.2f  %-16s\n",
                $status, $uid, $pid,
                (localtime $btime)[2,1,0],
                $etime / 100,
                $cmd;
}

# perl pacct.pl /var/log/account/pacct
# tail -f /var/log/account/pacct | perl pacct.pl

これは、ログファイル形式のバージョン3を想定しています。acct.h

ただし、ログファイルにはプロセス/スレッド名(例:実行可能ファイルのデフォルト名、15バイトに切り捨てて簡単に偽造することができますprctl(PR_SET_NAME))のみが含まれており、実行可能ファイルパスは含まれていないため、これはあまり役に立ちません。または、次のように呼び出します。パラメータ。

これは、スクリプトを展開してなどのフィールドも表示したい場合にstime便利ですutime

# translate comp_t to float
# utime, stime, mem, minflt, majflt are in the comp_t format
# io, rw, swaps are never set; they're purely decorative
sub comp2f {
        my $m = $_[0] & 0x1fff; my $e = $_[0] >> 13; $m * 8 ** $e;
}

メモ:acctパッケージをインストールする代わりに、次のコマンドを使用してプロセスアカウントを設定することもできます。

# mkdir /var/log/account
# perl -e 'require "syscall.ph"; my $f = shift;
  open my $h, ">>", $f or die "open >>$f: $!" if $f;
  $! = -syscall SYS_acct(), $f // 0 and die "acct $f: $!";
' /var/log/account/pacct

答え3

これ

  set -o pipefail 

あなたが望むものに非常に近いです。

パイプラインは、パイプラインのすべてのコンポーネントが完了するまで完了しません。戻り値は、失敗した最後のゼロ以外のコマンドの値、または失敗したコマンドがない場合は0になります。

したがって、40個のコマンドが一緒にパイプされ、3番目のコマンドが戻りコード8を提供し、残りのコマンドが正常に完了すると、戻りコード全体は8になります。どのコマンドが間違った戻りコードを提供するかを見つけるのは難しいでしょう。

関連情報