通过python3子进程发送管道命令 [英] Sending piped commands via python3 subprocess

查看:118
本文介绍了通过python3子进程发送管道命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过python3.4执行以下子过程命令

I am trying to execute the following subprocess command via python3.4

cd /home/mailer-domains/domain | rndc loadkeys domain

我已经尝试过使用.call和.Popen的多种方法,但是它要么不喜欢我的管道,要么不喜欢我的开关

I have tried numerous methods using .call and .Popen but it either doesn't like my pipe or it doesn't like my switch

>>> subprocess.call(['cd /home/mailer-domains/'+domain, '|', 'rndc', 'loadkeys', domain])    
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.4/subprocess.py", line 537, in call
    with Popen(*popenargs, **kwargs) as p:
  File "/usr/local/lib/python3.4/subprocess.py", line 859, in __init__
    restore_signals, start_new_session)
  File "/usr/local/lib/python3.4/subprocess.py", line 1457, in _execute_child
    raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'cd /home/mailer-domains/lecomm.com'

>>> subprocess.call(['cd /home/ex-mailer-domains/'+domain, '&&', 'rndc', 'loadkeys', domain]) 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.4/subprocess.py", line 537, in call
    with Popen(*popenargs, **kwargs) as p:
  File "/usr/local/lib/python3.4/subprocess.py", line 859, in __init__
    restore_signals, start_new_session)
  File "/usr/local/lib/python3.4/subprocess.py", line 1457, in _execute_child
    raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'cd /home/mailer-domains/lecomm.com'


>>> subprocess.call(['cd', '/home/mailer-domains/'+domain, '&&', 'rndc', 'loadkeys', domain])
cd: too many arguments
2


>>> subprocess.Popen(['cd', '/home/mailer-domains/'+domain, '&&', 'rndc', 'loadkeys', domain])    
<subprocess.Popen object at 0x805aa5860>
cd: too many arguments


>>> subprocess.call(['cd', '/home/mailer-domains/'+domain] '&&' ['rndc', 'loadkeys', domain])    
  File "<stdin>", line 1
    subprocess.call(['cd', '/home/mailer-domains/'+domain] '&&' ['rndc', 'loadkeys', domain])
                                                                 ^
SyntaxError: invalid syntax


>>> subprocess.call(['cd', '/home/mailer-domains/'+domain], '&&' ['rndc', 'loadkeys', domain])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: string indices must be integers


>>> subprocess.call(['cd', '/home/mailer-domains/'+domain], ['rndc', 'loadkeys', domain])     
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.4/subprocess.py", line 537, in call
    with Popen(*popenargs, **kwargs) as p:
  File "/usr/local/lib/python3.4/subprocess.py", line 767, in __init__
    raise TypeError("bufsize must be an integer")
TypeError: bufsize must be an integer


>>> subprocess.call(['cd', '/home/mailer-domains/'+domain] ['rndc', 'loadkeys', domain])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list indices must be integers, not tuple


>>> subprocess.call(['cd', '/home/mailer-domains/'+domain] +['rndc', 'loadkeys', domain])
cd: too many arguments
2


>>> ps = subprocess.Popen((['cd', '/home/mailer-domains/'+domain]), stdout = subprocess.PIPE)        
>>> output = subprocess.check_output((['rndc', 'loadkeys', domain]), stdin=ps.stdout)
rndc: 'loadkeys' failed: not found
no matching zone 'lecomm.com' in any view
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.4/subprocess.py", line 620, in check_output
    raise CalledProcessError(retcode, process.args, output=output)
subprocess.CalledProcessError: Command '['rndc', 'loadkeys', 'lecomm.com']' returned non-zero exit status 1


>>> output = subprocess.check_output((['rndc', 'loadkeys', domain]), stdin=ps.stdout, stdout=PIPE)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'PIPE' is not defined

如何通过Python3 subprocess正确发送2个管道命令?

How do I properly send 2 piped commands via Python3 subprocess?

推荐答案

答案可以在 subprocess模块中的函数通常不调用shell来解释命令,而是直接使用给定的参数调用它们!可以通过使用参数shell=True(来自Python文档的示例)来忽略此行为:

The functions from the subprocess module normally do not call a shell to interpret the commands, but rather invoke them directly with the given arguments! This behaviour can be overidden by using the argument shell=True (example from the Python documentation):

output = check_output("dmesg | grep hda", shell=True)

但是,如果命令和参数不是固定的,而是取决于用户的输入,则不建议这样做.然后,执行此操作的正确方法是使用两个Popen调用并手动构造管道(再次来自Python文档的代码示例):

However, this is not advisable if the command and arguments are not fix but depends on user input. Then, the correct way to do this is to use two Popen calls and construct the pipeline by hand (code example again from the Python documentation):

p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]

这篇关于通过python3子进程发送管道命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆