在 python 脚本中,我尝试运行一个子进程,使用以下命令侦听和接收文件ncat
:
proc = subprocess.Popen(command,stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
其中command
变量是这个列表:
command = ['nc', '-4', '-l', '10099', '>', '/tmp/files/copy_file_2_10099']
我收到错误:
Ncat: Got more than one port specification: 10000 > *path to file*
看起来它将>
和 路径字符串视为端口号。有任何想法吗?
答案1
问题是,据我们nc
所知,您正在提供>
和/tmp/files/copy_file_2_10099
作为最后两个参数。
模块中的 python Popen 函数subprocess
不执行 shell 重定向,因此它只是将这两个参数作为附加参数传递。在 shell 中运行时它起作用的原因是 shell> /tmp/files/copy_file_2_10099
在将参数传递给命令之前解释,因此命令永远看不到它们。 shell 处理打开文件并使用其文件描述符作为命令标准输出。
可以shell=True
向 Popen 添加参数,但它是建议您传递字符串而不是序列(一个数组,就像你做的那样)。如果您这样做,Popen 将启动一个 shell 来运行该命令,并将处理重定向。
如果您想在纯 python 中捕获命令的输出,可以通过向 Popen 调用提供stdout
(或) 参数来告诉 subprocces.Popen 使用文件对象。stderr
答案2
蟒蛇的subprocess.Popen()
接受可选的命名参数shell
,可以设置为True
通过 shell 运行命令行。
如果没有它(默认),它只会将作为原始参数给出的字符串传递给命令。有了它,您可能应该将命令行作为单个字符串给出。例如subprocess.run()
:
# raw strings, no shell
>>> proc = subprocess.run(["echo", "$$"])
$$
# with the shell
>>> proc = subprocess.run("echo shell pid is $$", shell=True)
shell pid is 14897
# this passes the first as the shell command line and others as $0, $1, $2
>>> args=['echo "$# args, arg #2 is: $2"', "sh", "abc", "def"]
>>> proc = subprocess.run(args, shell=True)
2 args, arg #2 is: def
所以你可能想要
command = "nc -1 -l 10099 > /tmp/files/copy_file_2_10099"
proc = subprocess.Popen(command,stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
或者您可以自己处理重定向,只需在 Python 中打开文件并通过stdout
.