Python 正在运行返回管道输入的命令
我将此Python 3代码存储在Python 正在运行返回管道输入的命令,python,bash,python-3.x,Python,Bash,Python 3.x,我将此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通过管道传
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)李>
- 管道的另一端连接到发送进程的标准输出文件描述符(1)
$ 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
#/bin/bash
粘虫=$$
#确定连接至标准DIN的管道:
myPipeNumber=$(readlink/proc/$myPid/fd/0 | sed-n's,^pipe:\[\([0-9]\+\)\]$,\1,;T;p')
如果[-z$myPipeNumber]];然后
echo“输入不是管道”
其他的
#查找将标准输出连接到管道的流程
senderPipe=$(find/proc-mindepth 3-maxdepth 3-path“*/fd/1”-lname”管道:\[$myPipeNumber\]”2>/dev/null)
senderPid=$(sed-n's,/proc/\([0-9]\+\)/.*,\1,;T;p'Std-in可以是一个文件或整个命令管道,也可以只是一个终端,因此通常没有“命令”这样的东西您可能会得到。确定sys.stdin
是否连接到磁盘文件或管道很有用,但可能不太需要知道管道另一端的实际命令。@chepner有没有办法找出sys.stdin
的来源?@OrangeFlash81您可以通过查看sys.stdin.isa来判断它来自管道tty()
当它是管道时,它将是False
,但我不知道如何找到另一端的内容,甚至不知道antlersoft提到的另一端有多少内容。如果脚本之前有一个由5个命令组成的字符串,你会想要什么?顺便提一下,为什么要重新实现nl
(或者,cat-n
)?看起来很有趣!我稍后会仔细看看。