2016-04-01 14 views
4

は、私はいくつかのパイプによる入力やプリントを受け入れるpipe.pyに保存されているこのPythonの3のコードを、持って返されたコマンドの実行を取得することライン・バイ・ライン:パイプで連結された入力

import sys 

for i, line in enumerate(sys.stdin): 
    print("{}: {}".format(i, line)) 

私はその後、バッシュでこれを実行できます。

$ echo "Test" | python pipe.py 
0: Test 

これは意図したとおりに機能が、実際にパイプで連結された入力が生じたコマンドの実行を取得する方法があれば私がに興味はありますさ。したがって、上記の例では、値Testがプログラムにパイプされましたが、この値を取得するためにecho "Test"が実行されました。

私のPythonプログラムでecho "Test"コマンドを文字列として受け取る方法はありますか?

+2

標準入力は、コマンドのファイル全体またはパイプライン、または端末だけである可能性があります。したがって、一般的には、取得できる「コマンド」はありません。 – antlersoft

+0

'sys.stdin'がディスク上のファイルやパイプにアタッチされているかどうかを判断するのに便利ですが、パイプのもう一方の端にある実際のコマンドを知る必要はないでしょう。 – chepner

+0

@chepner 'sys.stdin'の出所を知る方法はありますか? –

答えて

1

ファイルシステムが/procのときは、少なくともLinuxでは、a)あなたのstdinはパイプであり、b)パイプ送信者がまだいない場合、が可能です。

  • あなたのPythonスクリプトは、標準入力(ファイルディスクリプタ0)に接続された配管を持っています

    アイデアはチェックパイプエントリを対応するため/procファイルシステムにあります。

  • パイプのもう一方の端は、送信プロセスのstdoutファイル記述子(1)に接続されています。例として

、あなたのPythonスクリプトは、プロセスID 1001を持ち、送信者がPID 1000年を持っている、これはあなたが参照してくださいね何であると仮定すると:

$ ls -l /proc/1001/fd/0 
lr-x------ 1 user users 64 Sep 22 14:41 /proc/1001/fd/0 -> 'pipe:[507536]' 

$ ls -l /proc/1000/fd/1 
l-wx------ 1 user users 64 Sep 22 14:41 /proc/1000/fd/1 -> 'pipe:[507536]' 

ので/procで少し検索して、あなたはあなたが望むものを得ることができます。 は、ここでは、欲しいものないbashの例だ - 出力が

$ yes 1 2 | ./find-piper.sh 
sender pid is 21380, command is "yes 1 2 " 

あるfind-piper.shスクリプトは次のようになります。Pythonのに

#!/bin/bash 

myPid=$$ 

# determine pipe connected to stdin: 
myPipeNumber=$(readlink /proc/$myPid/fd/0 | sed -n 's,^pipe:\[\([0-9]\+\)\]$,\1,;T;p') 
if [[ -z $myPipeNumber ]] ; then 
    echo "input is not a pipe" 
else 
    # find process with stdout connected to our pipe 
    senderPipe=$(find /proc -mindepth 3 -maxdepth 3 -path "*/fd/1" -lname "pipe:\[$myPipeNumber\]" 2>/dev/null) 
    senderPid=$(sed -n 's,/proc/\([0-9]\+\)/.*,\1,;T;p' <<< "$senderPipe") 

    # report pid and command line of sender 
    if [[ -z $senderPid ]] ; then 
    echo "could not find sender pid" 
    else 
    echo "sender pid is $senderPid, command is \"$(tr '\000' ' ' </proc/$senderPid/cmdline)\"" 
    fi 
fi 

# eat input 
cat > /dev/null 

変換は、練習として残している。)

警告

  • しかし、echo "Test"は非常に速く完了するため、2番目の前提条件(「パイプ送信者はまだいない」)はあなたのケースでは与えられません。
  • 送信パイプが複数のコマンド(たとえば、(echo "Test"; sleep 2) | python pipe.py)で構成されている場合は、複数の送信者エントリがあります。
+0

興味深い見えます!私は後で詳しく見ていきます。 –

関連する問題