haofly
haofly

Reputation: 903

python: subprocess.communicate not working

I want to input one argument to the subprocess.communicate, but it always be out of my expects. the folder tree:

├── file1
├── file2
├── main.py

the content of main.py:

import subprocess
child = subprocess.Popen(["ls"], stdin=subprocess.PIPE,  universal_newlines=True)
filepath = '/Users/haofly'
child.communicate(filepath)

whatever i change the filepath to, the result only lists current folder(file1,file2,main.py).

Is I misunderstanding the communicate? How I send data to the Popen?

And how about ssh command if i want to send password?

subprocess.Popen(['ssh', 'root@ip'], stdin=subprocess.PIPE, universal_newlines=True)

Upvotes: 0

Views: 4411

Answers (3)

Pandrei
Pandrei

Reputation: 4951

I think you are missing the a shell parameter in your Popen call:

import subprocess
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
process.wait()
print process.returncode

'ls' is probably not the best command to illustrate the concept, but if you want to pass in arguments to a command you would have to do something similar to this:

cmd = ['cmd', 'opt1', 'optN']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE,
                           stdin=subprocess.PIPE)
out, err = p.communicate('args')
print out

Upvotes: 1

zwer
zwer

Reputation: 25789

You cannot 'pipe' data into ls - it lists directories based on the provided CLI arguments - but you should be able to use xargs to achieve what you want (essentially passing your folder as an argument to ls) if you don't want to provide it with the command itself:

import subprocess
child = subprocess.Popen(["xargs", "ls"], stdin=subprocess.PIPE, universal_newlines=True)
filepath = '/Users/haofly'
child.communicate(filepath)

Upvotes: 1

jasonharper
jasonharper

Reputation: 9597

When you use ls manually, do you type ls alone, hit Enter, and then type in the filepath in response to a prompt? That's how you're trying to use it here - the parameter to .communicate() becomes the subprocess's standard input, which in fact ls ignores completely. It wants the directory to list as a command-line parameter, which you would specify as ["ls", filepath].

Upvotes: 1

Related Questions