1

Hi I have to execute a shell command :diff <(ssh -n [email protected] cat /vms/cloudburst.qcow2.*) <(ssh -n [email protected] cat /vms/cloudburst.qcow2) I tried

cmd="diff <(ssh -n [email protected] cat /vms/cloudburst.qcow2.*) <(ssh -n [email protected] cat /vms/cloudburst.qcow2)"
args = shlex.split(cmd)
output,error = subprocess.Popen(args,stdout = subprocess.PIPE, stderr= subprocess.PIPE).communicate()

However I am getting an error diff: extra operand cat

I am pretty new to python. Any help would be appreciated

1
  • You are passing the parameters "<(ssh", "-n", "root@...", "cat" literally to the diff tool. When typing in a shell, the "<(...)" parts get evaluated first, and the resulting (file) is passed to the diff command as parameter instead. What shell are you using? Commented Jun 12, 2012 at 19:03

2 Answers 2

8

You are using <(...) (process substitution) syntax, which is interpreted by the shell. Provide shell=True to Popen to get it to use a shell:

cmd = "diff <(ssh -n [email protected] cat /vms/cloudburst.qcow2.*) <(ssh -n [email protected] cat /vms/cloudburst.qcow2)"
output,error = subprocess.Popen(cmd, shell=True, executable="/bin/bash", stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()

Since you don't want the Bourne shell (/bin/sh), use the executable argument to determine the shell to use.

Sign up to request clarification or add additional context in comments.

1 Comment

I tried that, however I am getting an error '/bin/sh: Syntax error: "(" unexpected'.
3

You are using a special syntax called process substitiution in your command line. This is supported by most modern shells (bash, zsh), but not by /bin/sh. Therefore, the method suggested by Ned might not work. (It could, if another shell provides /bin/sh and does not "correctly emulate" sh's behaviour, but it is not guaranteed to). try this instead:

cmd = "diff <(ssh -n [email protected] cat /vms/cloudburst.qcow2.*) <(ssh -n [email protected] cat /vms/cloudburst.qcow2)"
output,error = subprocess.Popen(['/bin/bash', '-c', cmd], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()

This is basically what the shell=True parameter does, but with /bin/bash instead of /bin/sh (as described in the subprocess docs).

1 Comment

perfect! simple, effective

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.