Como verificar por quanto tempo um processo está em execução?


243

Gostaria de evitar fazer isso iniciando o processo a partir de um aplicativo de monitoramento.

Respostas:


311

No Linux com o psfrom procps(-ng)(e na maioria dos outros sistemas, pois isso é especificado pelo POSIX):

ps -o etime= -p "$$" 

Onde $$está o PID do processo que você deseja verificar. Isso retornará o tempo decorrido no formato [[dd-]hh:]mm:ss.

O uso -o etimeinforma psque você deseja apenas o campo de tempo decorrido, e o =final do mesmo suprime o cabeçalho (sem, você obtém uma linha que diz ELAPSEDe depois o tempo na próxima linha; com, você obtém apenas uma linha com o tempo) .

Ou, com versões mais recentes do conjunto de ferramentas procps-ng (3.3.0 ou superior) no Linux ou no FreeBSD 9.0 ou superior (e possivelmente outros), use:

ps -o etimes= -p "$$"

(com um acréscimo s) para obter o tempo formatado em segundos, o que é mais útil em scripts.

No Linux, o psprograma obtém isso de /proc/$$/statonde um dos campos (consulte man proc) é a hora de início do processo. Infelizmente, este é o tempo especificado em jiffies (um contador de tempo arbitrário usado no kernel do Linux) desde a inicialização do sistema. Portanto, você deve determinar o tempo em que o sistema inicializou (a partir de /proc/stat), o número de instantes por segundo nesse sistema e, em seguida, fazer as contas para obter o tempo decorrido em um formato útil.

É ridiculamente complicado encontrar o valor de HZ (ou seja, instantes por segundo). Dos comentários no sysinfo.cpacote procps, pode-se A) incluir o arquivo de cabeçalho do kernel e recompilar se um kernel diferente for usado, B) usar a sysconf()função posix , que, infelizmente, usa um valor codificado embutido na biblioteca C, ou C) pergunte ao kernel, mas não há interface oficial para fazer isso. Portanto, o pscódigo inclui uma série de cláusulas pelas quais determina o valor correto. Uau.

Portanto, é conveniente psfazer tudo isso para você. :)

Como observa o usuário @ 336_, no Linux (isso não é portátil), você pode usar o statcomando para examinar as datas de acesso, modificação ou alteração de status do diretório /proc/$$(onde novamente $$é o processo de interesse). Todos os três números devem ser iguais, então

stat -c%X /proc/$$

fornecerá o tempo em que o processo $$começou, em segundos desde a época. Isso ainda não é exatamente o que você deseja, já que você ainda precisa fazer as contas para subtrair isso do tempo atual para obter o tempo decorrido - acho que algo como date +%s --date="now - $( stat -c%X /proc/$$ ) seconds"funcionaria, mas é um pouco desajeitado. Uma vantagem possível é que, se você usar a saída de formato longo como em -c%xvez de -c%X, obterá uma resolução maior que o número inteiro segundos. Mas, se você precisar, provavelmente deve usar a abordagem de auditoria de processos, porque o tempo de execução do comando stat interferirá na precisão.


1
Oi! É etime=um erro de digitação? Só consigo encontrar etimenas páginas do manual.
Kent Pawar

16
@KentPawar Não é um erro de digitação. O vazio =suprime o cabeçalho. Experimentá-lo sem, ou tentarps -p $$ -o etime="Silly Header Here"
mattdm

4
ps -p $ (descoberta de pgrep) -o etime =
mafrosis

1
Agradável. Eu prefiro etimesme como então é de leitura óptica
Asfand Qazi

1
@alexmurray Isso apenas chama sysconf()e, portanto, fornece o valor codificado da biblioteca C, conforme observado, não é?
mattdm

36

Portátil:

% ps -o stime,time $$
STIME     TIME
Jan30 00:00:06

isto é, o shell foi iniciado em 30 de janeiro e totalizou cerca de 6 segundos de tempo de CPU.

Pode haver maneiras mais precisas ou mais analisáveis, mas menos portáteis, de obter essas informações. Verifique a documentação do seu pscomando ou do seu procsistema de arquivos.

No Linux, essas informações estão presentes /proc/$pid/stat.

awk '{print "CPU time: " $14+$15; print "start time: " $22}' /proc/$$/stat

O tempo da CPU está em instantes; Não sei de imediato como encontrar o valor instável do shell. O horário de início é relativo ao horário de inicialização (encontrado em /proc/uptime).


3
Encontrar o valor de HZ (isto é, jiffies por segundo) acaba sendo ridiculamente complicado! Dos comentários no sysinfo.cpacote procps, pode-se: a) incluir o arquivo de cabeçalho do kernel (e recompilar se um kernel diferente for usado, b) usar a função posix sysconf (), que, infelizmente, usa um valor codificado compilado no a biblioteca c, ou c) pergunte ao kernel, e não há interface oficial para fazer isso. Portanto, o código inclui uma série de cláusulas pelas quais determina o valor correto. Uau.
mattdm

1
A página de psmanual afirma que timeé "tempo acumulado da CPU". Eu acho que o que o OP estava procurando etime, ou "o tempo decorrido desde que o processo foi iniciado". pubs.opengroup.org/onlinepubs/000095399/utilities/ps.html
rinogo

1
Afinal, não é tão "portátil": "ps: stime: palavra-chave não encontrada" no FreeBSD. Pelo menos suporta etime.
n.st

18
ps -eo pid,comm,cmd,start,etime | grep -i X

X é o nome do processo


2
provavelmente deve adicionar um grep -v grep.
Brian

ps -o pid,comm,cmd,start,etime -p Xpara olhar o PID X.
codeforester

13

pstoma uma -oopção para especificar o formato de saída e uma das colunas disponíveis é etime. De acordo com a página do manual:

etime - tempo decorrido desde o início do processo, no formato [[dd-] hh:] mm: ss.

Assim, você pode executar isso para obter o PID e o tempo decorrido de cada processo:

$ ps -eo pid,etime

Se você deseja o tempo decorrido de um PID específico (por exemplo, 12345), pode fazer algo como:

$ ps -eo pid,etime | awk '/^12345/ {print $2}'

( Edit : Acontece que há uma sintaxe mais curta para o comando acima; veja a resposta de mattdm )


5

Não sei por que isso ainda não foi sugerido: no Linux, você pode stat()o diretório / proc / [nnn] para o seu PID.

Esse comportamento foi projetado explicitamente para retornar o horário de início do processo, o que pode ser feito em alta resolução e o que o kernel pode executar com precisão sem os hacks do jiffies, já que o kernel pode (obviamente) simplesmente verificar as informações relevantes. Os campos de acesso, modificação de dados e alteração de status retornam o horário de início do processo.

O melhor de tudo é que você pode usá-lo stat(1)no shell ou na ligação apropriada stat(2)de $ favorite_programming_language, para que você nem precise iniciar um processo externo.

Observe que isso não funciona /usr/compat/linux/procno FreeBSD; os horários de acesso / modificação / alteração de status retornados são a hora atual e a hora do nascimento é a época do UNIX. Muito estúpido, o apoio não existe se você me perguntar.


Onde na saída do stat vejo as informações? Só vejo Acessar, Modificar e Alterar.
tshepang

@Tshepang Observe que esses valores são todos iguais e são a hora de início do processo. Você ainda precisa fazer as contas, mas isso é definitivamente melhor do que tentar descobrir instantes, conforme observado na minha resposta.
22817 mattdm #

Você chama assim: stat /proc/4480Isso fornecerá as datas de nascimento, alteração, modificação e acesso do processo. Se você precisar da identificação do processo, basta usar "top"
user890332

2

Se você pode executar o tempo e executar um comando, obterá exatamente o que está procurando. Você não pode fazer isso com um comando já em execução.

[0]% de tempo de sono 20

sono 20 0.00s usuário 0.00s sistema 0% cpu 20.014 total


Você sabe como posso fazer isso em um monitoramento de processo em execução até que ele termine?
precisa saber é o seguinte

1

você pode obter a hora de início do processo, observando o statarquivo stat produzido por proc, formatá-lo usando datee subtraí-lo do horário atual:

echo $(( $(date +%s) - $(date -d "$(stat /proc/13494/stat | grep Modify | sed 's/Modify: //')" +%s) ))

Onde 13494está o seu processo?


1

$ ps -eo lstart obter hora de início

$ ps -eo etime obter duração / tempo decorrido

$ ps -eo pid,lstart,etime | grep 61819
  PID                   STARTED     ELAPSED
  61819 Mon Sep 17 03:01:35 2018    07:52:15

61819 é o ID do processo.


O uso do lstart pode ser problemático, ele distorce - unix.stackexchange.com/questions/274610/…
slm

1

Tempo decorrido em segundos: expr $(date +"%s") - $(stat -c%X /proc/<PID HERE>)


Parece-me uma variação muito pequena de uma que o mattdm já mencionou : date +%s --date="now - $( stat -c%X /proc/$$
Jeff Schaller

Esse não funcionou para mim na minha instância mínima do docker Alpine, então escrevi este
Shardj
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.