Python subprocess.Popen for multiple python scripts - python

I am trying to understand the Popen method. I currently have three python files in the same directory: test.py, hello.py and bye.py. test.py is the file containing the subprocess.Popen method while hello and bye are simple hello world and goodbye world files i.e. they only contain a single print.
if I do:
import subprocess
from subprocess import PIPE
tst = subprocess.Popen(["python", "hello.py"], stdout=PIPE, stderr=PIPE)
(out,err) = tst.communicate()
Everything seems to work fine, obtaining in the shell the proper "Hello World" print for the hello.py and doing the same for bye.py the shell prints "GoodBye World" as it should.
The issue starts when I want to run both files,
import subprocess
from subprocess import PIPE
tst = subprocess.Popen(["python", "hello.py", "python", "bye.py"], stdout=PIPE, stderr=PIPE)
(out,err) = tst.communicate()
This will only return the print for the first .py file, and then return
[WinError 2 ] The system cannot find the file specified
This will happen if I also remove the second "python". Why is this happening?

This will happen if I also remove the second "python". Why is this happening?
Running
subprocess.Popen(["python", "hello.py", "python", "bye.py"]
is akin to running
$ python hello.py python bye.py
which doesn't really make a whole lot of sense, since that's interpreted as passing the arguments hello.py python bye.py to python.
So that's part 1, to your question "I am trying to understand the Popen method."
Without knowing what you actually want to do with this proof of concept, you have a few options; call multiple Popen() sequentially, or use a semicolon with shell=True, but make sure to consider the security implications of that:
# This will also break on Windows
>>> import subprocess as sp
>>> sp.check_output("python -V ; python -V", shell=True)
b'Python 3.8.2\nPython 3.8.2\n'

Related

How to pass python commands after opening a python console from a python script?

What I need here is opening a python console from python script and then pass commands to that python console.
I need to automate this process. Currntly I am using os.system and subprocess to open the python console but after that I am totally stuck with passing print("Test") to python console.
Here is the sample code which I am working on.
import os
os.system("python")
#os.system("print('Hello World'))
# or
import subprocess
subprocess.run("python", shell = True)
Please help me to understand how I can pass the nested commands.
Thanks
I have found a very helpful answer from another thread and applied to my use case.
from subprocess import run, PIPE
p = run(['python'], stdout=PIPE,
input='print("Test")\nprint("Test1")\nimport os\nprint(os.getcwd())', encoding='ascii')
print(p.returncode)
# -> 0
print(p.stdout)
It starts the python shell and then executes the following commands separated by \n.
Prints Test
Prints Test1
Imports OS
Get the current working directory.
Reference :
How do I pass a string into subprocess.Popen (using the stdin argument)?

Run .bat file using Python

I have a batch file, which I use to load some pre-build binaries to control my device.
It's command is:
cd build
java -classpath .;..\Library\mfz-rxtx-2.2-20081207-win-x86\RXTXcomm.jar -
Djava.library.path=..\Library\mfz-rxtx-2.2-20081207-win-x86 tabotSample/Good1
pause
Now, I want to run the batch file using Python, and I tried os.system(batch,bat), and I tried using Popen
import os
from subprocess import Popen
os.popen("cd TAbot")
r=os.popen("hello.bat")
However, the python console(Anaconda python 2.7) seems like executed the code, but returns nothing, and nothing happens.
I want to run this batch file from python, please help me.
by the way, I tried popen for another batch file like,
echo Hello but nothing happens.
Here is the simple solution.
from subprocess import Popen
import subprocess
def run_batch_file(file_path):
Popen(file_path,creationflags=subprocess.CREATE_NEW_CONSOLE)
run_batch_file('file_name.bat')
file_name.bat
echo .bat file running from python
pause
You can also use this
import subprocess
subprocess.call(["C:\\temp\\test.bat"], shell=False)
test.bat
copy "C:\temp\test.txt" "C:\temp\test2.txt"
I think this should work like this:
batch.py
from subprocess import Popen
p = Popen("test.bat", cwd=r"C:\path\to\batch\folder")
stdout, stderr = p.communicate()
test.bat
echo Hello World!
pause
Here many guys suggested very useful solutions, but I want to point the importance of where is the program located.
(Bat file is usually made for automation task to reduce time and this has high probability to work some task related path)
import subprocess
os.chdir("YOUR TARGET PATH")
exit_code = subprocess.call(FILEPATH)# FILEPATH is from the standpoint on YOUR TARGET PATH

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.

run perl script with python

I've been looking at multiple examples on here and elsewhere, but nothing seems for work for me. I know nothing about python. All I am trying to do is run a perl script simply located at
sdb1/media/process.pl
The example code that I've found runs all over the place, and mostly seems like it has extra stuff that I don't need. What I'm trying right now is
#! /usr/bin/python
pipe = subprocess.Popen(["perl", "/sdb1/media/process.pl"], stdout=subprocess.PIPE)
But that just gives me the error
NameError: name 'subprocess' is not defined
If I've missed anything important, let me know. Otherwise, thanks for your time.
you need to import the subprocess library to run subprocess
#! /usr/bin/python
import subprocess
pipe = subprocess.Popen(["perl", "/sdb1/media/process.pl"], stdout=subprocess.PIPE)
Alternatively, if you are just using that same function a lot of times, you can do
from subprocess import Popen
then you can just call
pipe = Popen(["perl", "/sdb1/media/process.pl"], stdout=subprocess.PIPE)
I would have commented but I need 50 rep.

Run a .bat file using python code

I try to run a .bat file in Windows using Python script.
ask.bat file:
Application.exe work.xml
I write Python code :
import os
os.system("D:\xxx1\xxx2XMLnew\otr.bat ")
Output: when try to run the file its just give a blink of the command prompt, and the work is not performing.
Note: I try with alternate slash also , but it is not working.
And I also want to save output of the file in another file.
Can anyone suggest how can I make the script runnable.
This has already been answered in detail on SO. Check out this thread, It should answer all your questions:
Executing a subprocess fails
I've tried it myself with this code:
batchtest.py
from subprocess import Popen
p = Popen("batch.bat", cwd=r"C:\Path\to\batchfolder")
stdout, stderr = p.communicate()
batch.bat
echo Hello World!
pause
I've got the batchtest.py example from the aforementioned thread.
import subprocess
filepath="D:/path/to/batch/myBatch.bat"
p = subprocess.Popen(filepath, shell=True, stdout = subprocess.PIPE)
stdout, stderr = p.communicate()
print p.returncode # is 0 if success
Replace \ with / in the path
import os
os.system("D:/xxx1/xxx2XMLnew/otr.bat ")
Probably the simplest way to do this is ->
import os
os.chdir("X:\Enter location of .bat file")
os.startfile("ask.bat")
It is better to write .bat file in such way that its running is not dependent on current working directory, i.e. I recommend to put this line at the beginning of .bat file:
cd "%~dp0"
Enclose filepath of .bat file in double quotes, i.e.:
os.system('"D:\\x\\so here can be spaces\\otr.bat" ["<arg0>" ["<arg1>" ...]]')
To save output of some batch command in another file you can use usual redirection syntax, for example:
os.system('"...bat" > outputfilename.txt')
Or directly in your .bat file:
Application.exe work.xml > outputfilename.txt
You are just missing to make it raw. The issue is with "\". Adding r before the path would do the work :)
import os
os.system(r"D:\xxx1\xxx2XMLnew\otr.bat")
So I do in Windows 10 and Python 3.7.1 (tested):
import subprocess
Quellpfad = r"C:\Users\MeMySelfAndI\Desktop"
Quelldatei = r"\a.bat"
Quelle = Quellpfad + Quelldatei
print(Quelle)
subprocess.call(Quelle)
python_test.py
import subprocess
a = subprocess.check_output("batch_1.bat")
print a
This gives output from batch file to be print on the python IDLE/running console. So in batch file you can echo the result in each step to debug the issue. This is also useful in automation when there is an error happening in the batch call, to understand and locate the error easily.(put "echo off" in batch file beginning to avoid printing everything)
batch_1.bat
echo off
echo "Hello World"
md newdir
echo "made new directory"
If you are trying to call another exe file inside the bat-file.
You must use SET Path inside the bat-file that you are calling.
set Path should point into the directory there the exe-file is located:
set PATH=C:\;C:\DOS {Sets C:\;C:\DOS as the current search path.}

Categories