python – 获取返回管道输入的命令

我有这个
Python 3代码存储在pipe.py中,它接受一些管道输入并逐行打印:

import sys

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

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

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

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

有没有办法在我的Python程序中将echo“Test”命令作为字符串?

最佳答案 这是可能的 – 至少在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”; sleep 2)| python pipe.py),那么您将找到多个发件人条目.

点赞