How can I create a simple BAT file that will run my python script located at C:\somescript.py?
c:\python27\python.exe c:\somescript.py %*
Open a command line (⊞ Win+R, cmd, ↵ Enter)
and type python -V, ↵ Enter.
You should get a response back, something like Python 2.7.1.
If you do not, you may not have Python installed. Fix this first.
Once you have Python, your batch file should look like
#echo off
python c:\somescript.py %*
pause
This will keep the command window open after the script finishes, so you can see any errors or messages. Once you are happy with it you can remove the 'pause' line and the command window will close automatically when finished.
Here's how you can put both batch code and the python one in single file:
0<0# : ^
'''
#echo off
echo batch code
python "%~f0" %*
exit /b 0
'''
print("python code")
the ''' respectively starts and ends python multi line comments.
0<0# : ^ is more interesting - due to redirection priority in batch it will be interpreted like :0<0# ^ by the batch script which is a label which execution will be not displayed on the screen. The caret at the end will escape the new line and second line will be attached to the first line.For python it will be 0<0 statement and a start of inline comment.
The credit goes to siberia-man
Just simply open a batch file that contains this two lines in the same folder of your python script:
somescript.py
pause
If you've added Python to your PATH then you can also simply run it like this.
python somescript.py
You can use python code directly in batch file,
https://gist.github.com/jadient/9849314.
#echo off & python -x "%~f0" %* & goto :eof
import sys
print("Hello World!")
See explanation, Python command line -x option.
--- xxx.bat ---
#echo off
set NAME1="Marc"
set NAME2="Travis"
py -u "CheckFile.py" %NAME1% %NAME2%
echo %ERRORLEVEL%
pause
--- yyy.py ---
import sys
import os
def names(f1,f2):
print (f1)
print (f2)
res= True
if f1 == "Travis":
res= False
return res
if __name__ == "__main__":
a = sys.argv[1]
b = sys.argv[2]
c = names(a, b)
if c:
sys.exit(1)
else:
sys.exit(0)
Similar to npocmaka's solution, if you are having more than one line of batch code in your batch file besides the python code, check this out: http://lallouslab.net/2017/06/12/batchography-embedding-python-scripts-in-your-batch-file-script/
#echo off
rem = """
echo some batch commands
echo another batch command
python -x "%~f0" %*
echo some more batch commands
goto :eof
"""
# Anything here is interpreted by Python
import platform
import sys
print("Hello world from Python %s!\n" % platform.python_version())
print("The passed arguments are: %s" % sys.argv[1:])
What this code does is it runs itself as a python file by putting all the batch code into a multiline string. The beginning of this string is in a variable called rem, to make the batch code read it as a comment. The first line containing #echo off is ignored in the python code because of the -x parameter.
it is important to mention that if you want to use \ in your batch code, for example in a file path, you'll have to use r"""...""" to surround it to use it as a raw string without escape sequences.
#echo off
rem = r"""
...
"""
This is the syntax:
"python.exe path""python script path"pause
"C:\Users\hp\AppData\Local\Programs\Python\Python37\python.exe" "D:\TS_V1\TS_V2.py"
pause
Basically what will be happening the screen will appear for seconds and then go off take care of these 2 things:
While saving the file you give extension as bat file but save it as a txt file and not all files and Encoding ANSI
If the program still doesn't run save the batch file and the python script in same folder and specify the path of this folder in Environment Variables.
If this is a BAT file in a different directory than the current directory, you may see an error like "python: can't open file 'somescript.py': [Errno 2] No such file or directory". This can be fixed by specifying an absolute path to the BAT file using %~dp0 (the drive letter and path of that batch file).
#echo off
python %~dp0\somescript.py %*
(This way you can ignore the c:\ or whatever, because perhaps you may want to move this script)
ECHO OFF
set SCRIPT_DRIVE = %1
set SCRIPT_DIRECTORY = %2
%SCRIPT_DRIVE%
cd %SCRIPT_DRIVE%%SCRIPT_DIRECTORY%
python yourscript.py`
i did this and works:
i have my project in D: and my batch file is in the desktop, if u have it in the same drive just ignore the first line and change de D directory in the second line
in the second line change the folder of the file, put your folder
in the third line change the name of the file
D:
cd D:\python_proyects\example_folder\
python example_file.py
Use any text editor and save the following code as runit.bat
#echo off
title Execute Python [NarendraDwivedi.Org]
:main
echo.
set/p filename=File Name :
echo.
%filename%
goto main
Now place this file in the folder where python script is present. Run this file and enter python script's file name to run python program using batch file (cmd)
Reference : Narendra Dwivedi - How To Run Python Using Batch File
Create an empty file and name it "run.bat"
In my case i use "py" because it's more convenient, try:
C:
cd C:\Users\user\Downloads\python_script_path
py your_script.py
#echo off
call C:\Users\[user]\Anaconda3\condabin\conda activate base
"C:\Users\[user]\Anaconda3\python.exe" "C:\folder\[script].py"
start xxx.py
You can use this for some other file types.
Related
I can run commands in prompt from a python script but I want to save the output to a specific file. This script will pull a directory listing:
import subprocess
subprocess.call('dir', shell=True)
and write to a file where my python program was ran:
import sys
sys.stdout = open('badfile', 'w')
print('test')
However I'm trying to combine the two so that the results from the Dir command will be appended to the file "badfile" in a specified location such as C:\users\idiot\somerandomdirectory and not just the default location.
Append output to a file
Q. I'm trying to combine the two so that the results from the Dir command will be appended to the file "badfile"
A. The Python answer is below this one ...
The Command Line Way ...
This can be done in python, but there are probably easier ways to achieve what you want. Here is one to consider:
The usual method is to use the Command Prompt or shell to do these things. You could still have a python script doing things, but then you run it from the command prompt and send the output somewhere else. The easiest way, the way that was designed for this exact case, is to use 'redirection.' You 'catch' the output from the program or script and send it somewhere else. This process is called 'redirection.'
This is how to do it for your example:
C:\myfolder> dir *.* >> C:\some\random\directory\badfile.txt
If you wanted to erase the file before sending your text, you would use a single > symbol instead of the >> notation.
Redirection
The general syntax for your example is:
COMMAND >> FILENAME (append COMMAND output to the end of FILENAME)
The >> symbol between the COMMAND and FILENAME is a 'redirection operator.'
A redirection operator is a special character that can be used with a command, like a Command Prompt command or DOS command, to either redirect the input to the command or the output from the command.
By default, when you execute a command, the input comes from the keyboard and the output is sent to the Command Prompt window. Command inputs and outputs are called command handles.
Here are some examples:
command > filename Redirect command output to a file
command >> filename APPEND into a file
command < filename Type a text file and pass the text to command
commandA | commandB Pipe the output from commandA into commandB
commandA & commandB Run commandA and then run commandB
commandA && commandB Run commandA, if it succeeds then run commandB
commandA || commandB Run commandA, if it fails then run commandB
I mostly use macOS nowadays, but the ideas are similar.
Here is a cheatsheet for Windows.
Here is a cheatsheet Linux and macOS.
The Pythonic Way
As for python, do this:
import subprocess
with open('C:/temp/badfile.txt', mode='at',) as f:
f.write(subprocess.check_output(['dir','*.*']).decode())
There. Done. Python really is great.
To have a program that takes in any command line arguments and writes the results to sp.log, like this:
sp dir *.* /w
create a python script called sp like this:
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
from subprocess import check_output
from sys import argv
if len(argv) > 1:
with open('sp.log', mode='at',) as f:
try:
f.write(check_output(argv[1:]).decode())
except Exception as e:
print(e)
There are a lot of other things you could add, like checking default encoding, making it work with windows/macOS/linux, adding error checking, adding debugging information, adding command line options ...
Here is a GIST of a longer and more detailed version that I threw together to play with:
https://gist.github.com/skeptycal
I am using a batch file to access my portable VLC executable to convert an mp4 to an mp3:
set arg1=%1 REM -> arg1={my_mp4_full_path}
set arg2=%2 REM -> arg2={my_mp3_full_path}
echo %arg1%
echo %arg2%
REM batch file is in the same directory as "VLCPlayer" folder
"%~dp0\VLCPlayer\VLCPortable.exe" -I dummy %arg1% --sout=#transcode{acodec=mp3,ab=128,vcodec=dummy}:std{access="file",mux="raw",dst=%arg2%} vlc://quit
When I run this script the first time, vlc crashes and I get an unplayable mp3 file, however when I run the script again the script works and I get a playable mp3. Is there a way to remedy this, or make it consistent? I don't see why running it twice would yield different outcomes.
No I don't have ffmpeg on my computer it is unrecognizable internal or external command.
Note that I face the same problem when using powershell to perform the same task, when I import my function from a .psm1 script:
function ConvertToMp3(
[switch] $inputObject,
[string] $vlc = '{PAth_TO_PORTABLE_VLC}\VLCPortable.exe')
{
PROCESS {
$codec = 'mp3';
$oldFile = $_;
$newFile = $oldFile.FullName.Replace($oldFile.Extension, ".$codec").Replace("'","");
&"$vlc" -I dummy "$oldFile" ":sout=#transcode{acodec=$codec,
vcodec=dummy}:standard{access=file,mux=raw,dst=`'$newFile`'}" vlc://quit | out-null;
# delete the original file
Remove-Item $oldFile;
}
}
I get the same random output that sometimes works, sometimes crashes.
Update:
I feel like I should add more info of how I use the batch file:
I have a python script Convert.py and I call my batch file inside using os.system():
mp4_to_convert = arguments.file
full_path_mp4 = os.path.join(outdir,mp4_to_convert)
mp3_to_convert_to = mp4_to_convert.replace(".mp4",".mp3")
full_path_mp3 = os.path.join(outdir,mp3_to_convert_to)
command_string = """Convert_Script.bat \"{}\" \"{}\"""".format(full_path_mp4, full_path_mp3)
os.system(command_string)
This is the documentation of os.system():
os.system(command)
Execute the command (a string) in a subshell. This
is implemented by calling the Standard C function system(), and has
the same limitations. Changes to sys.stdin, etc. are not reflected in
the environment of the executed command. If command generates any
output, it will be sent to the interpreter standard output stream.
On Unix, the return value is the exit status of the process encoded in
the format specified for wait(). Note that POSIX does not specify the
meaning of the return value of the C system() function, so the return
value of the Python function is system-dependent.
On Windows, the return value is that returned by the system shell
after running command. The shell is given by the Windows environment
variable COMSPEC: it is usually cmd.exe, which returns the exit status
of the command run; on systems using a non-native shell, consult your
shell documentation.
Any pointers or suggestions would be helpful, thank you in advance for your help.
I have a batch script which is generating a configuration file after its execution, the configuration file generated has some data inside it. When i execute it from command prompt as follows i get the desired output :
C:/> start.bat
but if i try to execute from python script as follows or even if i double click and execute it i do get the configuration file but it does not contain any required data it just have '0' inside it:
import subprocess as sp
p= sp.Popen("C:/pathtobatch/start.bat",stdin=sp.PIPE, stdout = sp.PIPE, stderr=sp.PIPE)
Inside the batch script(start.bat) i am actually executing a python script and retrieving its data to a configuration file as follows:
python C:\inetpub\ftproot\sample.py > log.txt
set myvar =< log.txt
del log.txt
echo %errorlevel% %myvar% >C:\inetpub\ftproot\config.txt
I need to execute the batch(start.bat) from the python script and generate the config.txt file having the required data. So, how shall i do that.
Why the start.bat is not working fine if i double click it and why is it working fine if i am executing it from command prompt.
Is it possible that you get '0' as it is the value of %errorlevel%?
I found two issues in your case:
1) batch file - can you please update your batch file to something like:
for /f %%i in ('python C:\inetpub\ftproot\sample.py') do set myvar=%%i
echo %errorlevel% %myvar% >C:\inetpub\ftproot\config.txt
Credit for the idea of setting variable: https://stackoverflow.com/a/2340018/5088142
2) python script - can you please update your python script to be:
import os
os.system("C:/pathtobatch/start.bat")
I'm having trouble finding many resources, but I'm trying to get vba to run a python script
Const pyScript = "C:\Test\Weekend_Exceptions\Weekend_Exception.py"
Dim dblRetVal As Double
dblRetVal = Shell("C:\Python34\python.exe " & pyScript)
I know my python script works and should output a file, but its not. Additionally the vba is not tirggering a debug flag so I'm not sure where I am wrong. Any advice would be appreciated.
You don't give too much details so i'll make some assumptions
Probably your python script read some local file this will cause your script to raise a FileNotFoundError and exit
To make the test copy the entire arg string to Shell, in your case "C:\Python34\python.exe C:\Test\Weekend_Exceptions\Weekend_Exception.py", open a cmd with Win+r , paste and run, not being in the right directory should raise the same error.
If this is the problem, make a makestuff.bat file with the code
#echo off
#cd C:\Test\Weekend_Exceptions\
#C:\Python34\python.exe Weekend_Exception.py
#echo on
Then call the bat from Shell("C:\Place\of\your\bat\makestuff.bat")
Return with more details to we work on a solution
Here is how I did:
I created a File1.bat to open the File2.py. The code in File1.bat is:
#echo off
#h:
#cd H:\Path\Cronus\Rangers
#C:\Python3\python.exe File2.py
#echo on
Note that File2.py is inside H:\Path\Cronus\Rangers folder. That's why we need to open it before.
I created a function in VBA to open a .bat file:
Option Compare Database
Function MacroPythonSARH()
On Error GoTo MacroPythonSARH_Err
Call Shell("H:\Path\Cronus\Rangers\File1.bat", 1)
MacroPythonSARH_Exit:
Exit Function
MacroPythonSARH_Err:
MsgBox Error$
Resume MacroPythonSARH_Exit
End Function
I have a batch file that runs a python script. I am running Python 3.2. I want to send a variable like an integer or string from the python script back to the batch file, is this possible?
I know I can accept command line arguments in the Python script with sys.argv. Was hoping there was some feature that allows me to do the reverse.
In your Python script, just write to standard out: sys.stdout.write(...)
I'm not sure what scripting language you are using, maybe you could elaborate on that, for now I'll assume you are using bash (unix shell).
So, In your batch script you can have the output of the python script into a variable like this:
#run the script and store the output into $val
val = `python your_python_script.py`
#print $val
echo $val
EDIT it turns out, it is Windows batch
python your_python_script.py > tmpFile
set /p myvar= < tmpFile
del tmpFile
echo %myvar%
If a int is enough for you, then you can use
sys.exit(value)
in your python script. That exits the application with a status code of value
In your batch file you can then read it as the %errorlevel% environment variable.
You can't "send" a string. You can print it out and have the calling process capture it, but you can only directly return numbers from 0 through 255.
Ignacio is dead on. The only thing you can return is your exit status. What I've done previously is have the python script (or EXE in my case) output the next batch file to be run, then you can put in whatever values you'd like and run it. The batch file that calls the python script then calls the batch file you create.
You can try this batch script for this issue, as an example:
#echo off
REM %1 - This is the parameter we pass with the desired return code for the Python script that will be captured by the ErrorLevel env. variable.
REM A value of 0 is the default exit code, meaning it has all gone well. A value greater than 0 implies an error
REM and this value can be captured and used for any error control logic and handling within the script
set ERRORLEVEL=
set RETURN_CODE=%1
echo (Before Python script run) ERRORLEVEL VALUE IS: [ %ERRORLEVEL% ]
echo.
call python -c "import sys; exit_code = %RETURN_CODE%; print('(Inside python script now) Setting up exit code to ' + str(exit_code)); sys.exit(exit_code)"
echo.
echo (After Python script run) ERRORLEVEL VALUE IS: [ %ERRORLEVEL% ]
echo.
And when you run it a couple of times with different return code values you can see the expected behaviour:
PS C:\Scripts\ScriptTests> & '\TestPythonReturnCodes.cmd' 5
(Before Python script run) ERRORLEVEL VALUE IS: [ 0 ]
(Inside python script now) Setting up exit code to 5
(After Python script run) ERRORLEVEL VALUE IS: [ 5 ]
PS C:\Scripts\ScriptTests> & '\TestPythonReturnCodes.cmd' 3
(Before Python script run) ERRORLEVEL VALUE IS: [ 0 ]
(Inside python script now) Setting up exit code to 3
(After Python script run) ERRORLEVEL VALUE IS: [ 3 ]
PS C:\Scripts\ScriptTests