GNU/Linux >> Linux Esercitazione >  >> Linux

Come determini il comando effettivo che ti sta convogliando?

la pipe apparirà come una voce nell'elenco dei descrittori di file aperti del tuo processo:

 % 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

potresti anche usare qualcosa come:

 % 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

quindi, allora hai l'inode della pipe :) ora puoi cercare ogni altro processo sotto /proc/ per quel tubo quindi avrai il comando che ti sta reindirizzando:

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

in questo esempio, cat convogliato ai reparti sh . in /proc/29889 puoi trovare un file chiamato cmdline che ti dice, come si chiamava esattamente:

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

i campi della riga di comando sono separati da NUL, quindi sembra un po' brutto :)


Akira ha suggerito di usare lsof .

Ecco come puoi scriverlo:

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

Eseguendolo:

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

Un altro modo è utilizzare i gruppi di processi.

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

Eseguendolo:

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

Nota che entrambi funzionano solo se il comando sul lato sinistro della pipe viene eseguito abbastanza a lungo per ps per vederlo. Hai detto che lo stavi usando con tail -f , quindi dubito che questo sia un problema.

$ sleep 0 | ./whatpipe1.sh 

$ sleep 1 | ./whatpipe1.sh
sleep 1

Linux
  1. Come utilizzare il comando basename?

  2. Come eseguire un comando che prevede il reindirizzamento o il piping con Sudo?

  3. Come determinare la codifica dei caratteri utilizzata da un terminale in un programma C/c++?

  4. Linux:come avviare Puppy Linux Slacko nella riga di comando?

  5. Come puoi determinare le versioni installate delle librerie glibc?

Come utilizzare il comando cronologia di Linux

Comando file Linux:come determinare il tipo di file in Linux

Come utilizzare il comando di lettura Bash

Come utilizzare il comando xargs di Linux

Come si configura il prompt dei comandi in Linux per mostrare la directory corrente?

Cosa significa avere * * * nel comando traceroute ? e come puoi far fronte a questa situazione?