4

I have a python script in which I need to invoke a shell command. The shell command can accept its input from either a file or stdin.

In my script, the input is stored in a variable. What is the proper way to invoke the command? If it matters, the shell command produces no output.

I know I could write the variable's content into a file and invoke the command with the file as argument but that seems inelegant. Surely, there's a better way.

Can someone tell me what it is? Thanks.

LenB
  • 1,126
  • 2
  • 14
  • 31
  • I think this answer will be helpful for you http://stackoverflow.com/a/8475367/1374493 – palvarez89 Feb 08 '16 at 01:13
  • You should have been able to Google this. – Riaz Feb 08 '16 at 01:17
  • Possible duplicate of [Wrapping an interactive command line application in a python script](http://stackoverflow.com/questions/1567371/wrapping-an-interactive-command-line-application-in-a-python-script) – ivan_pozdeev Feb 08 '16 at 01:19
  • Possible duplicate of [how do i write to a python subprocess' stdin](http://stackoverflow.com/questions/8475290/how-do-i-write-to-a-python-subprocess-stdin) – palvarez89 Feb 08 '16 at 01:22

2 Answers2

4

You can use the subprocess module.

import subprocess
process = subprocess.Popen(["Mycommand", "with", "arguments"], stdin=subprocess.PIPE)
process.communicate("My text")
zondo
  • 19,901
  • 8
  • 44
  • 83
  • "Use communicate() rather than .stdin.write, .stdout.read or .stderr.read to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process." (From https://docs.python.org/2/library/subprocess.html) – palvarez89 Feb 08 '16 at 01:13
  • @palvarez89 Good call. I fixed it. – zondo Feb 08 '16 at 01:17
  • `communicate()` is a one-off method. To do that repeatedly, I copied some code from its implementation that handled `stdin` in a separate thread. – ivan_pozdeev Feb 08 '16 at 01:20
  • @ivan_pozdeev My answer *did* use `process.stdin.write`, but as palvarez89 mentioned, that is not the preferred way. The OP mentioned trying to `write the variable's content into a file and invoke the command with the file as argument`. If it were a problem to use a one-off method, that would not have been suggested. – zondo Feb 08 '16 at 01:23
0

Refer to How do I pass a string into subprocess.Popen (using the stdin argument)?

For python 3.5+ (3.6+ for encoding), you can use input:

from subprocess import check_output   
output = check_output(["cat","-b"],
        input="-foo\n-bar\n-foobar", encoding='ascii')
print(output)

example

ntg
  • 12,950
  • 7
  • 74
  • 95