Execute shell command and retrieve stdout in Python [duplicate] - python

This question already has answers here:
How do I execute a program or call a system command?
(65 answers)
Convert POSIX->WIN path, in Cygwin Python, w/o calling cygpath
(4 answers)
Closed 7 years ago.
In Perl, if I want to execute a shell command such as foo, I'll do this:
#!/usr/bin/perl
$stdout = `foo`
In Python I found this very complex solution:
#!/usr/bin/python
import subprocess
p = subprocess.Popen('foo', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout = p.stdout.readlines()
retval = p.wait()
Is there any better solution ?
Notice that I don't want to use call or os.system. I would like to place stdout on a variable

An easy way is to use sh package.
some examples:
import sh
print(sh.ls("/"))
# same thing as above
from sh import ls
print(ls("/"))

Read more of the subprocess docs. It has a lot of simplifying helper functions:
output = subprocess.check_output('foo', shell=True, stderr=subprocess.STDOUT)

You can try this
import os
print os.popen('ipconfig').read()
#'ipconfig' is an example of command

Related

How to run shell-commands in Python? [duplicate]

This question already has answers here:
How to run Python's subprocess and leave it in background
(2 answers)
Closed 1 year ago.
This post was edited and submitted for review 1 year ago and failed to reopen the post:
Original close reason(s) were not resolved
I made a remote-control client which can receive commands from the server. The commands that are received will be executed as normal cmd commands in a shell. But how can I execute these commands in the background so that the user wont see any in- or output.
For example when I do this, the user would see anything whats going on:
import os
os.system(command_from_server)
You can using subprocess Popen to start a cmd without waiting for end:
from subprocess import Popen
pid = Popen(["ls", "-l"]).pid
Popen has a lot of configure options for handling stdout and stderr. See the ufficial doc.
To execute a command in background, you have to use the subprocess module.
For example:
import subprocess
subprocess.Popen("command", shell=True)
If you want to execute command with more than one argument eg: ls -a, the code is a bit different:
import subprocess
subprocess.Popen("ls -a", shell=True)
To change the directory you can use the os module:
import os
os.chdir(path)
But, as mentioned from tripleee in the comments bellow, you can also pass the cwd parameter to the subprocess.Popen-Method.

How to use STDIN from subprocess.Popen [duplicate]

This question already has answers here:
How do I pass a string into subprocess.Popen (using the stdin argument)?
(12 answers)
Closed 6 years ago.
How can I implement something like
$ echo "hello" | my_app
with usage of Python's subprocess?
subprocess.Popen() expects a pipe or a file handle for STDIN. But I want to provide STDIN for the called program via a variable. So something like
myinput = "hello"
subprocess.Popen("an_external_programm", stdin=myinput)
….
I was able to solve my problem by using Popen.communicate()
So some kind of pseudo code:
proc = subprocess.Popen(…)
proc.communicate(input="my_input_via_stdin")
In a python script named myscript.py
import sys
for line in sys.stdin:
print(line)
in unix
echo 'hello' | myscript.py

Failed to run shell commands with subprocess [duplicate]

This question already has answers here:
Why subprocess.Popen doesn't work when args is sequence?
(3 answers)
Closed 6 years ago.
In my terminal if I run: echo $(pwd), I got /home/abr/workspace, but when I tried to run this script in python like this:
>>> import subprocess
>>> cmd = ['echo', '$(pwd)']
>>> subprocess.check_output(cmd, shell=True)
I get '\n'. How to fix this?
Use os package:
import os
print os.environ.get('PWD', '')
From the documentation on the subprocess module:
If args is a sequence, the first item specifies the command string,
and any additional items will be treated as additional arguments to
the shell itself.
You want:
subprocess.check_output("echo $(pwd)", shell=True)
Try this:
cmd = 'echo $(pwd)'
subprocess.check_output(cmd, shell=True)
In subprocess doc it specified that cmd should be a string when shell=True.
From the documentation:
The shell argument (which defaults to False) specifies whether to use
the shell as the program to execute. If shell is True, it is
recommended to pass args as a string rather than as a sequence.
A better way to achieve this is probably to use the os module from the python standard library, like this:
import os
print os.getcwd()
>> "/home/abr/workspace"
The getcwd() function returns a string representing the current working directory.
The command subpreocess.check_output will return the output of the command you are calling:
Example:
#echo 2
2
from python
>>>subprocess.check_output(['echo', '2'], shell=True)
>>>'2\n'
the '\n' is included because that is what the command does it prints the output sting and then puts the current on a new line.
now back to your problem; assuming you want the output of 'PWD', first of all you have to get rid of the shell. If you provide the shell argument, the command will be run in a shell environment and you won't see the returned string.
subprocess.check_output(['pwd'])
Will return the current directory + '\n'
On a personal note, I have a hard time understanding what you are trying to do, but I hope this helps solve it.

Open .bat from python [duplicate]

This question already has answers here:
Run a .bat file using python code
(9 answers)
Closed 5 years ago.
I have a .bat in a folder with an exe named abcexport.exe with the following code inside :
abcexport.exe myswf.swf
Double-clicking the bat as normally on windows exports the swf as expected.
I need to do this from within python, but it complains abcexport is “not recognized as an internal or external command”.
My code :
Attempt 1 -
os.startfile("path\\decompiler.bat")
Attempt 2 -
subprocess.call([path\\decompiler.bat"])
Also tried the same with os.system(), and with subprocess method Popen, and passing the argument shell=True ends up in the same
You can use this
from subprocess import Popen
p = Popen("batch.bat", cwd=r"C:\Path\to\batchfolder")
stdout, stderr = p.communicate()
A .bat file is not executable. You must use cmd.exe (interpretor) to "run it". Try
import subprocess
executable="path\\decompiler.bat"
p = subprocess.Popen(["C:\Windows\System32\cmd.exe", executable, 'myswf.swf'], shell=True, stdout = subprocess.PIPE)
p.communicate()
in order of the .bat to work

Python command execution output [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Running shell command from python and capturing the output
I want to capture the output of a command into a variable, so later that variable can be used again. I need to change this script so it does that:
#!/usr/bin/python
import os
command = raw_input("Enter command: ")
os.system(command)
If I enter "ls" when I run this script, I get this output:
Documents Downloads Music Pictures Public Templates Videos
I want to capture that string (the output of the ls command) into a variable so I can use it again later. How do I do this?
import subprocess
command = raw_input("Enter command: ")
p = subprocess.Popen(command, stdout=subprocess.PIPE)
output, error = p.communicate()
The output of the command can be captured with the subprocess module, specifically, the check_output function..
output = subprocess.check_output("ls")
See also the documentation for subprocess.Popen for the argument list that check_output takes.
This is the way I've done it in the past.
>>> import popen2
__main__:1: DeprecationWarning: The popen2 module is deprecated. Use the subprocess module.
>>> exec_cmd = popen2.popen4("echo shell test")
>>> output = exec_cmd[0].read()
>>> output
'shell test\n'

Categories