I am trying to execute the following subprocess command via python3.4
cd /home/mailer-domains/domain | rndc loadkeys domain
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
How do I properly send 2 piped commands via Python3 subprocess
?
The answer can be found in the subprocess documentation.
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)
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]
You don't need pipes at all, just pass the cwd
to to subprocess:
subprocess.call(['rndc', 'loadkeys', domain],cwd='/home/mailer-domains/'+domain)
If you did wanted to change directory for more than just the subprocess, you should use os.chdir
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With