Linux: Como saber onde um processo foi iniciado e como foi iniciado?

34

Eu estava checando uma caixa do Linux e encontrei um processo perl em execução e tendo uma boa parte do uso da CPU. Com top, eu só poderia perl no nome do processo.

Quando pressionei c , para visualizar a linha de comando, ele mostrava / var / spool / mail. O que não faz sentido, pois esse é o diretório.

Minhas perguntas são:

1) Por que isso aconteceu? Como esse processo perl pode mascarar sua linha de comando? 2) Qual é a maneira mais confiável de descobrir onde e como um processo foi iniciado?

Obrigado!

Fernando
fonte

Respostas:

36

Na maioria dos casos, apenas a execução psé geralmente suficiente, juntamente com seus sinalizadores favoritos para permitir uma saída ampla. Eu me inclino ps -feww, mas as outras sugestões aqui funcionarão. Observe que, se um programa foi iniciado a partir de alguém $PATH, você verá apenas o nome do executável, não o caminho completo. Por exemplo, tente o seguinte:

$ lftp &
$ ps -feww | grep ftp
lars      9600  9504  0 11:30 pts/10   00:00:00 lftp
lars      9620  9504  0 11:31 pts/10   00:00:00 grep ftp

É importante observar que as informações visíveis pspodem ser completamente substituídas pelo programa em execução. Por exemplo, este código:

int main (int argc, char **argv) {
        memset(argv[0], ' ', strlen(argv[0]));
        strcpy(argv[0], "foobar");
        sleep(30);
        return(0);
}

Se eu compilar isso em um arquivo chamado "myprogram" e executá-lo:

$ gcc -o myprogram myprogram.c
$ ./myprogram &
[1] 10201

E, em seguida ps, execute , vou ver um nome de processo diferente:

$ ps -f -p 10201
UID        PID  PPID  C STIME TTY          TIME CMD
lars     10201  9734  0 11:37 pts/10   00:00:00 foobar

Você também pode olhar diretamente /proc/<pid>/exe, o que pode ser um link simbólico para o executável apropriado. No exemplo acima, isso fornece informações muito mais úteis do que ps:

$ls -l /proc/9600/exe
lrwxrwxrwx. 1 lars lars 0 Feb  8 11:31 /proc/9600/exe -> /usr/bin/lftp
larsks
fonte
11
no total, os arquivos /procfornecerão todas as informações sobre um programa, exeserão um link para o executável, cwdo diretório de trabalho atual, o fddiretório contém links para os arquivos abertos (incluindo entrada padrão, saída e erro padrão)
Hubert Kario
57

A maneira mais confiável é olhar para o /procdiretório do processo. Cada processo possui um /proc/<pid>/diretório no qual mantém informações como:

  1. cwd link para o diretório de trabalho atual
  2. fd um diretório com links para os arquivos abertos (descritores de arquivo)
  3. cmdline leia-o para ver qual linha de comando foi usada para iniciar o processo
  4. environ as variáveis ​​de ambiente para esse processo
  5. root um link para o que o processo considera como diretório raiz (será / a menos que seja chroot)

Há mais informações interessantes sobre cada processo / processo, mas com os itens acima você será capaz de saber exatamente o que está acontecendo.

Além disso, o uso ps auxfmostrará quem bifurcou o que, para que você tenha uma idéia melhor de quem está chamando seu perl.

coredump
fonte
Eu sempre uso o Process Explorer no Windows e me perguntei se havia um equivalente no Linux. Essa opção faz tudo! ps auxf ... legal!
Yanick Girouard
11
+1 para o parâmetro f para ps, isso foi feito por mim!
Lennart Rolland
2
+1 por me ensinar o que parece ser um conceito tão fundamental ... /proccontém informações do processo! quem sabia?? tudo que eu sempre olhei lá para era versione cpuinfoe outras coisas ... mais isso resolve o meu problema real porque a versão do meu router de ps ignora todos os parâmetros
Nacht - Reintegrar Monica
@ Coredump: e se o processo chamado chroot()antes, como posso saber qual diretório /proc/ᴘɪᴅ/cwdcorresponde?
precisa saber é o seguinte
10

para mim, agora, descobri que pstreedava uma indicação muito mais clara de como um processo foi iniciado, do queps aux

Se parece com isso:

  ├─lightdm─┬─Xorg
  │         ├─lightdm─┬─init─┬─apache2───2*[apache2───26*[{apache2}]]
  │         │         │      ├─at-spi-bus-laun─┬─dbus-daemon
  │         │         │      │                 └─3*[{at-spi-bus-laun}]
  │         │         │      ├─at-spi2-registr───{at-spi2-registr}
  │         │         │      ├─dbus-daemon
  │         │         │      ├─dropbox───29*[{dropbox} ]
etc-infinito
fonte
2

Tente ps axww | grep perlobter a linha de comando completa do seu processo. Parece que topacabou de cortar uma longa fila.

Alex
fonte
2

Tente usar o comando fuser -vu /var/spool/mail Este comando exibe os PIDs dos processos usando os arquivos ou sistemas de arquivos especificados. No modo de exibição padrão, cada nome de arquivo é seguido por uma letra indicando o tipo de acesso:

c - diretório atual. e - executável sendo executado. f - abre arquivo. f é omitido no modo de exibição padrão. r - diretório raiz. m - arquivo mapeado ou biblioteca compartilhada.

Talvez isso o ajude a avançar sua pesquisa para responder ao que você está procurando. Não sei se isso ajuda, mas talvez você descubra algumas informações úteis.

panaroik
fonte
1

Sem consultar a página de manual para obter os sinalizadores exatos, uma maneira fácil de definir qual é a linha de comando e a hora de início, o ps auxwww deve funcionar. Você pode torná-lo mais elegante, se desejado, lendo a página de manual.

Jason Tan
fonte
1

Dois comandos vêm à mente:

1) obtenha a hora de início do processo fora de ' ps '.

$ ps -ax -o pid,start,comm
  PID  STARTED COMMAND         USER
    1   Feb 06 init            root
    2   Feb 06 kthreadd        root
[...]
  13147 19:09:48 chrome          hcooper
  13270 19:13:51 chrome          hcooper
  13386 19:18:34 bash            hcooper

2) lastcomm , que agora verifico, não tenho instalado. De qualquer forma, a descrição da página de manual diz:

   lastcomm prints out information about previously executed commands. If
   no arguments are specified, lastcomm will print info about all of the
   commands in acct (the record file).

Mas como algumas pessoas disseram, "ls -al / proc /" dirá muito!

Cooperativas
fonte
0

você pode usar:

systemctl status <PID>

ou com o nome do processo:

systemctl status $(pgrep perl)

Isso fornecerá informações sobre serviços systemd que iniciaram seu processo.

Encontrei essa dica aqui

TVK
fonte