我有这个
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),那么您将找到多个发件人条目.