9

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?

3
  • What are you trying to achieve by piping the output of cd (which is normally empty) into the rndc process? Do you really just want to run rndc in the new directory? Commented Dec 14, 2015 at 0:02
  • @TomDalton I am assuming the loadkey switch looks in the current directory. I saw some odd behavior that indicated this. I have numerous zone directories each with their own keys. Commented Dec 14, 2015 at 0:13
  • though, I am pondering to myself, that sounds silly. Commented Dec 14, 2015 at 0:14

2 Answers 2

10

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]
Sign up to request clarification or add additional context in comments.

5 Comments

There is no need for a pipe at all. the cwd can be passed to subprocess
@PadraicCunningham Agreed in this case. However, someone searching for the title of this question will almost certainly be interested in this answer.
There are 1000 dupes of how to pipe, this is not the approach to take for the OP, piping when you can pass the directory makes no sense
@PadraicCunningham: 1001... :D
Well it sure helped me out! Thanks @Sebastian Riese
5

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.