Run a .bat file using python code - python

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.}

Related

Python subprocess.Popen for multiple python scripts

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'

Using python, how to find a different python script in a directory and then run it

Using python, I need to find another python script file in a directory and then run it
system = input("Enter system name: ")
for filename in listdir(directory):
if filename.find(system + "_startup") != -1 and filename.endswith(".py"):
# import and run specific startup script
I know how to find and open a file normally, and I know how to call one python script from another script, but I don't really know how to bridge the gap here.
Each system I'm working with will have a different "startup" script which runs. I don't want to have to import every single startup file I have into my main script (there's a lot of startup scripts) only the specific one for the system of interest. Is there a way for me to achieve this without importing all the startup files?
If all you need to do is execute the script, one option is to spawn a new process:
import subprocess
subprocess.run(["python3", filename])
Why not use os.system to execute the command in a subshell?
os.system('py -3 ' + filepath)
for catch output bash
import subprocess
from subprocess import Popen
system = input("Enter system name: ")
for filename in listdir(directory):
if filename.find(system + "_startup") != -1 and filename.endswith(".py"):
p = Popen(["python3",filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, errors = p.communicate()
# catch output bash
print(output)
# catch erro bash
print(errors)

Execute windows shell command and process output variables

In Python 3.7 running on Windows, what specific syntax is required to:
1. Navigate to a directory containing a terraform program
2. Execute "terraform apply -auto-approve" in that target directory
3. Extract the resulting output variables into a form usable in python
The output variables might take the form:
security_group_id_nodes = sg-xxxxxxxxxx
vpc_id_myvpc = vpc-xxxxxxxxxxxxx
Want to be using windows cmd style commands here, NOT powershell.
My first failed newbie attempt is:
import os
os.chdir('C:\\path\\to\\terraform\\code')
from subprocess import check_output
check_output("terraform apply -auto-approve", shell=True).decode()
Not sure about your output, but subprocess could definitely make the trick.
Try something like:
command = 'terraform apply -auto-approve'
TARGET_DIR = 'E:\Target\Directory'
subprocess_handle = subprocess.Popen(shlex.split(command), cwd=TARGET_DIR, shell=False, stdout=subprocess.PIPE)
subprocess_handle.wait()
result = subprocess_handle.communicate()[0]
print(result)
Worked for me once, just play around with params.
UPD: Here I assume that "terraform" is an executable.

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

running windows command line program from python with ini file argument

Im trying to run a windows command line application from a python script with a ini config file in the command which i suspect isnt passing when its executed.
The command is c:\BLScan\blscan.exe test.ini.
The ini file is the config file that the application needs to know what parameters to scan with.
This is the script im using
import subprocess
from subprocess import Popen, PIPE
cmd = '/blscan/blscan test.ini'
p = Popen(cmd , stdout=PIPE, stderr=PIPE)
out, err = p.communicate()
print "Return code: ", p.returncode
print out.rstrip(), err.rstrip()
When I use subprocess.popen to call the application it doesnt look to be reading the ini file. The device line is an indicator that the tuner hasnt been identified from the ini file so the program is dropping to the default tuner.
Return code: 0
BLScan ver.1.1.0.1091-commited
Config name: .\test.ini
Device 0: TBS 6925 DVBS/S2 Tuner
Device number: Total Scan Time = 0.000s
Transponders not found !
>>>
This is how it looks when run from the dos shell.
C:\BLScan>blscan test.ini
BLScan ver.1.1.0.1091-commited
Config name: .\test.ini
Scan interval 0
From 3400 to 3430 Mhz, Step 5 Mhz, Horizontal, Minimal SR 1000 KS, Maximal SR 10
0000 KS
3400 Mhz ...
3405 Mhz ...
3410 Mhz ...
Any advice would be appreciated
When you run this from the DOS shell, your current working directory is C:\BLscan, as is obvious from the prompt you show:
C:\BLScan>blscan test.ini
You can also tell from the error output that it's definitely looking in the current working directory. (Some Windows programs will, e.g., try the same directory as the executable… but you can't count on that, and this one does not.)
Config name: .\test.ini
So, if your current directory were not C:\BLScan, it wouldn't work from the DOS shell either. Try this:
C:\BLScan>cd \
C:\>\BLScan\blscan test.ini
You will get the exact same error you're getting in Python.
If you can't rely on being in C:\BLScan, you have to pass an absolute path. For example, this will work again:
C:\>\BLScan\blscan \BLScan\test.ini
Python is no different from the shell here. If you give it a relative path like test.ini, it will use the current working directory. So, you have the same two options:
os.chdir('/blscan')
p = subprocess.popen('blscan test.ini')
… or:
p = subprocess.popen(r'\BLScan\blscan \BLScan\test.ini')
You most likely need pass the path to the ini as well as to the exe:
clst = [r'C:\blscan\blscan.exe', r'C:\blscan\test.ini']
p = Popen(clst, stdout=PIPE, stderr=PIPE)
# etc . . .
If you pass Popen a list, it will quote out the args correctly for you.
Try passing the arguments to the subprocess.call as an array:
subprocess.call(["/blscan/blscan.exe","test.ini"])
Also, based on the command line versus py output in your question, double check that your blscan.exe tool works even when your "working directory" is different. Maybe you need to needs to be in the same working directory where blscan.exe is located.
os.chdir("C:\BLScan")

Categories