Linux: ¿Cómo saber dónde se inició un proceso y cómo se inició?

34

Estaba marcando una casilla de Linux y encontré un proceso perl ejecutándose y tomando una buena parte del uso de la CPU. Con la parte superior, solo pude perl en el nombre del proceso.

Cuando presioné c , para ver la línea de comandos, mostraba / var / spool / mail. Lo que no tiene sentido, ya que este es el directorio.

Mis preguntas son:

1) ¿Por qué sucedió esto? ¿Cómo este proceso de Perl podría enmascarar su línea de comandos? 2) ¿Cuál es la forma más confiable de averiguar dónde y cómo se inició un proceso?

¡Gracias!

Fernando
fuente

Respuestas:

36

En la mayoría de los casos, solo correr pses suficiente, junto con sus banderas favoritas para permitir una salida amplia. Me inclino hacia ps -feww, pero las otras sugerencias aquí funcionarán. Tenga en cuenta que si un programa se inició desde el de alguien $PATH, solo verá el nombre del ejecutable, no la ruta completa. Por ejemplo, intente esto:

$ 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

Es importante tener en cuenta que el psprograma en ejecución puede sobrescribir completamente la información visible en . Por ejemplo, este código:

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

Si compilo esto en un archivo llamado "myprogram" y lo ejecuto:

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

Y luego ejecutar ps, veré un nombre de proceso 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

También puede mirar directamente /proc/<pid>/exe, que puede ser un enlace simbólico al ejecutable apropiado. En el ejemplo anterior, esto le brinda mucha más información útil que ps:

$ls -l /proc/9600/exe
lrwxrwxrwx. 1 lars lars 0 Feb  8 11:31 /proc/9600/exe -> /usr/bin/lftp
larsks
fuente
1
en total, los archivos en /procproporcionarán toda la información sobre un programa, exeserán un enlace al ejecutable, cwdal directorio de trabajo actual, el fddirectorio contiene enlaces a archivos abiertos (incluyendo entrada estándar, salida y error estándar)
Hubert Kario
57

La forma más confiable es mirar el /procdirectorio para el proceso. Cada proceso tiene un /proc/<pid>/directorio donde guarda información como:

  1. cwd enlace al directorio de trabajo actual
  2. fd un directorio con enlaces a los archivos abiertos (descriptores de archivo)
  3. cmdline léelo para ver qué línea de comando se usó para iniciar el proceso
  4. environ las variables de entorno para ese proceso
  5. root un enlace a lo que el proceso considera que es el directorio raíz (será / a menos que esté chrooteado)

Hay más información interesante sobre cada proceso / proceso, pero con los anteriores podrás saber exactamente lo que está sucediendo.

Además, el uso ps auxfle mostrará quién bifurcó qué para que pueda tener una mejor idea de quién llama a su perl.

volcado de memoria
fuente
Siempre uso Process Explorer en Windows y me preguntaba si había un equivalente en Linux. ¡Ese interruptor lo hace todo! ps auxf ... bien!
Yanick Girouard
1
¡+1 para el parámetro f para ps, eso lo hizo por mí!
Lennart Rolland
2
+1 por enseñarme lo que parece un concepto tan fundamental ... ¡ /proccontiene información de proceso! ¿¿quien sabe?? todo lo que siempre veía allí por era versiony cpuinfoy esas cosas ... además de esto resuelve mi problema real, porque la versión de mi enrutador de ps ignora todos los parámetros
Nacht - Restablecer Monica
@coredump: y si el proceso llamó chroot()antes, ¿cómo puedo saber a qué directorio /proc/ᴘɪᴅ/cwdcorresponde?
user2284570
10

Para mí, justo ahora, descubrí que pstreedaba una indicación mucho más clara de cómo se inició un proceso, queps aux

se parece a esto:

  ├─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} ]
infinito-etcétera
fuente
2

Intenta ps axww | grep perlobtener la línea de comando completa de tu proceso. Parece que topacaba de recortar una línea larga.

Alex
fuente
2

Intente usar el comando fuser -vu /var/spool/mail Este comando le mostrará los PID de los procesos que utilizan los archivos o sistemas de archivos especificados. En el modo de visualización predeterminado, cada nombre de archivo va seguido de una letra que indica el tipo de acceso:

c - directorio actual. e - ejecutable que se está ejecutando. f - abrir archivo. f se omite en el modo de visualización predeterminado. r: directorio raíz. m: archivo mmap'ed o biblioteca compartida.

Tal vez le ayudará a avanzar en su búsqueda para responder la respuesta que está buscando. No sé si te ayuda, pero quizás encuentres información útil.

Panaroik
fuente
1

Sin consultar en la página del manual las marcas exactas, una manera fácil de financiar cuál es la línea de comando y la hora de inicio, ps auxwww debería funcionar. Si lo desea, puede hacerlo más elegante leyendo la página del manual.

Jason Tan
fuente
1

Dos comandos me vienen a la mente:

1) obtenga la hora de inicio del proceso 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 ahora verifico , no tengo instalado. De todos modos, la descripción de la página man dice:

   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).

Pero como algunas personas han dicho, "ls -al / proc /" te dirá mucho.

Cooperativas
fuente
0

puedes usar:

systemctl status <PID>

o con el nombre del proceso:

systemctl status $(pgrep perl)

Esto entregará información sobre los servicios de systemd que iniciaron su proceso.

Encontré esta pista aquí

TVK
fuente