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의 답변) 마지막 네 번째.

답변2

데비안을 사용하는 경우 이 acct패키지를 설치하여 프로세스 계정을 활성화할 수 있지만 종료 상태나 프로세스를 종료하는 신호 등은 표시되거나 표시되지 lastcomm --debug않습니다 .dump-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이 아닌 명령의 값이거나 실패한 명령이 없는 경우 0이 됩니다.

따라서 40개의 명령이 함께 파이프되어 있고 세 번째 명령이 반환 코드 8을 제공하고 나머지 명령이 성공적으로 완료되면 전체 반환 코드는 8이 됩니다. 어떤 명령이 잘못된 반환 코드를 제공하는지 알아내는 것은 까다로울 것입니다.

관련 정보