GNU/Linux >> Linux の 問題 >  >> Linux

パイピングされている実際のコマンドをどのように判断しますか?

パイプは、プロセスの開いているファイル記述子のリストにエントリとして表示されます:

 % 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

次のようなものも使用できます:

 % 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

したがって、パイプの inode があるよりも :) /proc/ の下で他のすべてのプロセスを検索できるようになりました そのパイプのために。次に、あなたにパイプしているコマンドがあります:

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

この例では、cat 病棟 sh にパイプで送られました . /proc/29889cmdline というファイルがあります。 正確には何と呼ばれていたかがわかります:

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

コマンド ラインのフィールドは NUL で区切られているため、見栄えが悪くなります :)


Akira は lsof の使用を提案しました .

スクリプトを作成する方法は次のとおりです:

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

実行:

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

もう 1 つの方法は、プロセス グループを使用することです。

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

実行:

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

どちらも、パイプの左側のコマンドが ps の十分な時間実行される場合にのみ機能することに注意してください。 それを見るために。 tail -f で使用していると言いました ので、これは問題ではないと思います。

$ sleep 0 | ./whatpipe1.sh 

$ sleep 1 | ./whatpipe1.sh
sleep 1

Linux
  1. basenameコマンドの使用方法は?

  2. Sudoを使用したリダイレクトまたはパイピングを含むコマンドを実行するにはどうすればよいですか?

  3. 端末がC/c ++プログラムで使用する文字エンコードを判別する方法は?

  1. Linux –パピーリナックスラコをコマンドラインで起動する方法は?

  2. 入力したすべてのコマンドをログに記録するにはどうすればよいですか?

  3. インストールされている glibc ライブラリのバージョンを確認するにはどうすればよいですか?

  1. コマンドの出力をクリップボードに直接コピーするにはどうすればよいですか?

  2. コマンド traceroute に * * * があるとはどういう意味ですか?その状況にどのように対処できますか。

  3. dd コマンドの最適なバイト サイズを決定する方法