Existe uma maneira de obter um status de saída do processo após muitos outros comandos terem sido emitidos no linux?

7

Se eu tiver muitos comandos que eu emiti e eu quiser que o status de saída de um processo que saiu diga 100 comandos atrás. Existe uma estrutura, localização de arquivos ou variável no Linux? Eu posso acessar todos os processos que saíram e ver informações sobre eles?

    
por mutant_city 19.09.2018 / 20:51

3 respostas

3

Se a contabilidade de processo do BSD foi ativada ( accton on foi emitida), com GNU acct 6.6.3 ou superior, você pode obter essa informação de lastcomm --debug ou dump-acct /var/log/account/pact (ou onde quer que os dados contábeis do processo sejam armazenados no seu sistema).

$ perl -e 'exit 123'
$ lastcomm --debug | grep perl
CURRENT REC: perl            |v3|     0.00|     0.00|     0.00|  1000|  1000| 26328.00|     0.00|     332|    8530|     |     123|pts/1   |Wed Sep 19 20:21:26 2018
$ dump-acct /var/log/account/pacct | grep perl
perl            |v3|     0.00|     0.00|     0.00|  1000|  1000| 26328.00|     0.00|     332|    8530|     |     123|pts/1   |Wed Sep 19 20:21:26 2018

Você obtém o código de saída no terceiro último campo e se ele foi morto ou não (mas não o número do sinal, consulte @sorrvy answer for that ) em o quarto último.

    
por 19.09.2018 / 21:23
2

Se você estiver no debian, poderá instalar o pacote acct para ativar a contabilidade do processo, mas observe que nem lastcomm --debug nem dump-acct mostram nada como o status de saída ou o sinal que encerrou um processo.

Se a ordem para obter esses dados, você pode usar um script como este:

$ 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};
$/ = ;
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

Isso pressupõe a versão 3 do formato de arquivo de log - consulte acct.h .

Observe, no entanto, que isso não é útil, porque apenas o nome do processo / encadeamento está incluído no arquivo de log (isto é, o nome básico do executável, truncado para 15 bytes e que pode ser facilmente falsificado com prctl(PR_SET_NAME) ) , não o caminho do executável ou os argumentos com os quais foi invocado.

Se você deseja estender esse script para exibir também os campos stime , utime , etc, isso pode ser útil:

# 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;
}
    
por 20.09.2018 / 01:40
-1

O

  set -o pipefail 

é bem parecido com o que você quer; será

A pipeline will not complete until all components of the pipeline have completed, and the return value will be the value of the last non-zero command to fail or zero if no command has failed.

Portanto, se você tiver 40 comandos reunidos e o terceiro comando fornecer um código de retorno 8 e o restante for concluído com êxito, o código de retorno geral será 8. Para descobrir qual comando deu o código de retorno incorreto, complicado.

    
por 19.09.2018 / 21:06