获取返回管道输入的命令运行

时间:2016-04-01 15:24:55

标签: python bash python-3.x

我将这个Python 3代码存储在import sys for i, line in enumerate(sys.stdin): print("{}: {}".format(i, line)) 中,它接受一些管道输入并逐行打印:

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

然后我可以在Bash中运行它:

Test

这是按预期工作的,但我感兴趣的是,是否有办法实际获得导致管道输入的命令运行。因此,对于上面的示例,值echo "Test"被传送到程序中,但执行echo "Test"以获取此值。

有没有办法可以在我的Python程序中将with open('verbatim.csv', 'r') as csvfile: reader = unicode_csv_reader(csvfile, dialect=csv.excel) for data in reader: tokens = nltk.word_tokenize(data) 命令作为字符串获取?

1 个答案:

答案 0 :(得分:1)

这是可能的 - 至少在Linux上有/proc文件系统,如果a)你的stdin完全是管道而b)管道发送器没有消失爱好。

想法是检查/proc文件系统中是否有相应的管道条目

  • 您的Python脚本的管道连接到stdin(文件描述符0)。
  • 管道的另一端连接到发送过程的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脚本如下所示:

#!/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

转换为Python留作练习:)

<强>注意事项

  • 然而,在您的情况下,第二个前提条件(“管道发送器尚未消失”)将不会给出,因为echo "Test"将非常快地完成。
  • 如果您的发件人管道包含多个命令(例如(echo "Test"; sleep 2) | python pipe.py),那么您将找到多个发件人条目。