GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo determinas el comando real que te está llegando?

la tubería aparecerá como una entrada en la lista de descriptores de archivos abiertos de su proceso:

 % ls -l /proc/PID/fd
 lr-x------ 1 xyz xyz 64 Feb 11 08:05 0 -> pipe:[124149866]
 lrwx------ 1 xyz xyz 64 Feb 11 08:05 1 -> /dev/pts/2
 lrwx------ 1 xyz xyz 64 Feb 11 08:05 2 -> /dev/pts/2
 lr-x------ 1 xyz xyz 64 Feb 11 08:05 10 -> /tmp/foo.sh

también podrías usar algo como:

 % lsof -p PID
 sh      29890 xyz  cwd    DIR   0,44    4096  77712070 /tmp
 sh      29890 xyz  rtd    DIR   0,44    4096  74368803 /
 sh      29890 xyz  txt    REG   0,44   83888  77597729 /bin/dash
 sh      29890 xyz  mem    REG   0,44 1405508  79888619 /lib/tls/i686/cmov/libc-2.11.1.so
 sh      29890 xyz  mem    REG   0,44  113964  79874782 /lib/ld-2.11.1.so
 sh      29890 xyz    0r  FIFO    0,6         124149866 pipe
 sh      29890 xyz    1u   CHR  136,2                 4 /dev/pts/2
 sh      29890 xyz    2u   CHR  136,2                 4 /dev/pts/2
 sh      29890 xyz   10r   REG   0,44      66  77712115 /tmp/foo.sh

Entonces, ahora tiene el inodo de la tubería :) ahora puede buscar cualquier otro proceso en /proc/ por esa pipa. entonces tendrás el comando que te está canalizando:

 % lsof | grep 124149866 
 cat     29889 xyz    1w  FIFO                0,6          124149866 pipe
 sh      29890 xyz    0r  FIFO                0,6          124149866 pipe

en este ejemplo, cat canalizado a las salas sh . en /proc/29889 puedes encontrar un archivo llamado cmdline que te dice, cómo se llamaba exactamente:

 % cat /proc/29889/cmdline
 cat/dev/zero%  

los campos de la línea de comando están separados por NUL, por lo que se ve un poco feo :)


Akira sugirió usar lsof .

Así es como podría escribirlo:

whatpipe2.sh

#!/bin/bash

pid=$$
pgid=$(ps -o pgid= -p $pid)
lsofout=$(lsof -g $pgid)
pipenode=$(echo "$lsofout" | awk '$5 == "0r" { print $9 }')
otherpids=$(echo "$lsofout" | awk '$5 == "1w" { print $2 }')
for pid in $otherpids; do
    if cmd=$(ps -o cmd= -p $pid 2>/dev/null); then
        echo "$cmd"
        break
    fi
done

Ejecutándolo:

$ tail -f /var/log/messages | ./whatpipe2.sh
tail -f /var/log/messages
^C

Otra forma es usar grupos de procesos.

whatpipe1.sh

#!/bin/bash    

pid=$$
# ps output is nasty, can (and usually does) start with spaces
# to handle this, I don't quote the "if test $_pgrp = $pgrp" line below
pgrp=$(ps -o pgrp= -p $pid)
psout=$(ps -o pgrp= -o pid= -o cmd=)
echo "$psout" | while read _pgrp _pid _cmd; do
    if test $_pgrp = $pgrp; then
        if test $_pid != $pid; then
            case $_cmd in
            ps*)
                # don't print the "ps" we ran to get this info
                # XXX but this actually means we exclude any "ps" command :-(
                ;;
            *)
                echo "$_cmd"
                ;;
            esac
        fi
    fi
done

Ejecutándolo:

$ tail -f /var/log/messages | ./whatpipe1.sh
tail -f /var/log/messages
^C

Tenga en cuenta que ambos solo funcionan si el comando en el lado izquierdo de la tubería se ejecuta durante el tiempo suficiente para ps para verlo. Dijiste que lo estabas usando con tail -f , así que dudo que esto sea un problema.

$ sleep 0 | ./whatpipe1.sh 

$ sleep 1 | ./whatpipe1.sh
sleep 1

Linux
  1. ¿Cómo registrar cada comando escrito?

  2. ¿Cómo puede determinar las versiones instaladas de las bibliotecas glibc?

  3. ¿Cómo puedo copiar la salida de un comando directamente en mi portapapeles?

  4. ¿Cómo configurar el símbolo del sistema en Linux para mostrar el directorio actual?

  5. ¿Cómo puedes ver el enlace duro real por ls?

Cómo usar el comando de historial de Linux

Comando de archivo de Linux:cómo determinar el tipo de archivo en Linux

Cómo usar el comando de lectura Bash

Cómo usar el comando xargs de Linux

Linux:¿cómo iniciar Puppy Linux Slacko en la línea de comandos?

Comando tr:cómo reemplazar la cadena \n con una nueva línea real (\n)