GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana Anda menentukan perintah aktual yang disalurkan ke Anda?

pipa akan muncul sebagai entri dalam daftar deskriptor file terbuka dari proses Anda:

 % 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

Anda juga bisa menggunakan sesuatu seperti:

 % 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

jadi, daripada Anda memiliki inode dari pipa :) sekarang Anda dapat mencari setiap proses lainnya di bawah /proc/ untuk pipa itu. maka Anda akan memiliki perintah yang dikirimkan kepada Anda:

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

dalam contoh ini, cat disalurkan ke ward sh . di /proc/29889 Anda dapat menemukan file bernama cmdline yang memberi tahu Anda, apa sebenarnya yang disebut:

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

bidang baris perintah dipisahkan oleh NUL, sehingga terlihat agak jelek :)


Akira menyarankan untuk menggunakan lsof .

Inilah cara Anda membuat skripnya:

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

Menjalankannya:

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

Cara lain adalah menggunakan grup proses.

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

Menjalankannya:

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

Perhatikan bahwa keduanya hanya berfungsi jika perintah di sisi kiri pipa berjalan cukup lama untuk ps untuk melihatnya. Anda bilang Anda menggunakannya dengan tail -f , jadi saya ragu ini adalah masalah.

$ sleep 0 | ./whatpipe1.sh 

$ sleep 1 | ./whatpipe1.sh
sleep 1

Linux
  1. Bagaimana Cara Menjalankan Perintah Yang Melibatkan Pengalihan Atau Perpipaan Dengan Sudo?

  2. Bagaimana Cara Menentukan Pengkodean Karakter yang Digunakan Terminal Dalam Program C/c++?

  3. Linux – Bagaimana Cara Mem-boot Puppy Linux Slacko Ke Baris Perintah?

  1. Bagaimana Anda bisa menentukan versi terinstal dari pustaka glibc?

  2. Bagaimana saya bisa menyalin output dari perintah langsung ke clipboard saya?

  3. Bagaimana Anda mengkonfigurasi command prompt di Linux untuk menampilkan direktori saat ini?

  1. Bagaimana Anda menggunakan ekspresi reguler dengan perintah cp di Linux?

  2. Apa artinya * * * dalam perintah traceroute ? dan Bagaimana Anda dapat mengatasi situasi tersebut?

  3. Cara menentukan ukuran byte terbaik untuk perintah dd