I have a batch file which when executed sets PATHs, prompts user for input and loads a script via Python. The python script creates a grid with the size of each cell determined by the user input variable (cellsize). The following is from my .bat file:
#echo off
rem Root OSGEO4W home dir to the following directory
call "C:\OSGeo4W64\bin\o4w_env.bat"
rem List available o4w programs
rem but only if osgeo4w called without parameters
#echo on
set PYTHONPATH=C:\OSGeo4W64\apps\qgis\python
set PATH=C:\OSGeo4W64\apps\qgis\bin;%PATH%
#echo off
echo.
set /p cellsize="Enter cellsize: "
cellsize=1
cmd /k python "Script.py" %cellsize%
#echo on
The .bat works the way it's supposed to, I obtain the correct results, but I receive the following error:
'cellsize' is not recognized as an internal or external command, operable program or batch file
What simple mistake(s) did I make? I am a beginner but still learning.
The line must read:
set cellsize=1
but surely this line seems more useful before the set /p line as an initialization, since otherwise it cancels the effect of that line.
#echo off
echo.
set /p cellsize="Enter cellsize: "
set cellsize=1
cmd /k python "Script.py" %cellsize%
#echo on
you need set
Related
I'm trying to get a batch-file to execute the following code:
cmd /K C:\ProgramData\Anaconda3\Scripts\activate.bat C:\ProgramData\Anaconda3
cd C:\ProgramData\Anaconda3\Lib\site-packages\tabpy_server\
run startup.bat
The first line execute properly and opens an anaconda python command-prompt window. The next lines fail to execute.
What am I missing?
The idea is to create a batch file which can be added to windows task-scheduler to start the tabpy server service.
There is no run command in batch. What you want is the start command. Also you want to use call instead of cmd /k because it is used for starting another instance of cmd while you just want to call the batch file. Here is an example:
call C:\ProgramData\Anaconda3\Scripts\activate.bat C:\ProgramData\Anaconda3
cd C:\ProgramData\Anaconda3\Lib\site-packages\tabpy_server\
start startup.bat
I'm trying to write a batch file to execute a python script and not having much luck. I tried the following:
#echo off
SET path C:\"Program Files\python37\python.exe"
C:\"projects\systemcheck.py -c systems.csv"
but get the following error:
C:\projects>nexus-script.bat Environment variable path C:\"Program
Files\python37\python.exe" not defined 'C:\"projects\systemcheck.py -c
systems.csv"' is not recognized as an internal or external command,
operable program or batch file.
It may be easiest to specify the full path to the Python executable. That way you don't have to worry about the PATH environment variable.
#echo off
"C:\Program Files\python37\python.exe" C:\projects\systemcheck.py -c systems.csv
If you absolutely need to set the PATH environment variable, you would do it like this:
#echo off
SET "PATH=C:\Program Files\python37;%PATH%"
python C:\projects\systemcheck.py -c systems.csv
Note that the path to the Python folder goes before the previous contents of PATH; this ensures that that is the Python that gets run if you have multiple Python installations on you computer.
You need to have your FULL path in quotes. Example: SET path to "C:\Program Files\python37\python.exe"
You don't need to SET the path, you can do what Jack mentioned in a past comment.
I am trying to run python script from windows cmd. When I run it under linux I put
python myscript.py filename??.txt
it goes through files with numbers from filename01.txt to filename18.txt and it works.
I tried to run it from cmd like
python myscript.py filename*.txt
or
python myscript.py filename**.txt
but it didnt work. If I tried the script on one single file in windows cmd it works.
Do you have any clue where the problem could be?
Thanks!
Unix shell convert file path pattern to actual files, then pass the result to the program. (python myscript.py)
But in Windows cmd, this does not happen.
See glob.glob if you want get file list that match the pattern.
Those wildcards are expanded at "shell (i.e. bash) level" before running your python script.
So the problem doesn't reside in python, but in the "shell" that you are using on Windows.
Probably you cloud try PowerShell for Windows or bash via CygWin.
try this:
FOR %X IN (filename*.txt) DO (python myscript.py %X)
Edit, you can create a .bat with this and try it.
setlocal EnableDelayedExpansion
set files=
FOR %%X IN (filename*.txt) DO set files=!files! %%X
echo %files%
python myscript.py %files%
From batch file
for %%f in ("filename*.txt") do python myscript.py "%%~nxf"
%%f will get a reference to each of the files. For each of them execute your script. %%~nxf will expand to name and extension of file.
From command line, replace %% with a single %
EDITED - I missunderstood the problem. Next try.
In windows, there is no default expansion of wildcard arguments ( see here). So, to get the same result you will need a batch file. It will concatenate the list of files and pass it to your python script
#echo off
setlocal enabledelayedexpansion
set "fileList="
for %%f in ("*.txt") do set "fileList=!fileList! "%%f""
python myscript.py !fileList!
endlocal
For a more reusable code, use something as (script calls are only echoed to screen to show efect of parameters and to avoid unneeded execution, remove when it works as intended)
#echo off
setlocal enableextensions
call :glob "*.txt" true fileList
echo python myscript.py %fileList%
echo.
call :glob "*.txt" false fileList
echo python myscript.py %fileList%
exit /b
:glob pattern useFullPath outputList
setlocal enabledelayedexpansion
if /i "%~2"=="true" (set "_name=%%%%~ff") else (set "_name=%%%%~nxf")
set "_list="
for %%f in ("%~1") do set "_list=!_list! "%_name%""
endlocal & if not "%~3"=="" set "%~3=%_list%"
As falsetru notes, on Windows the shell doesn't expand the wildcards for you, so the correct answer is glob.glob(). You should iterate over all the command line arguments and expand each. This works fine in Linux/UNIX too, because the expansion of an argument without any wildcards in it (which is what the shell gives you) is the unchanged filename. So something like this, using lazy evaluation to handle a potentially large number of args:
from sys import argv
from glob import glob
from itertools import chain, islice
for name in chain.from_iterable(glob(name) for name in islice(argv, 1, None)):
# do something with each file
I'm on Windows. I am trying to write a Python 2.x script (let's call it setup.py) which would enable the following scenario:
User runs cmd to open a console window
In that console window, user runs setup.py
User finds themselves in the same console window, but now the cmd running there has had its environment (env. variables) modified by setup.py
setup.py modifies the environment by adding a new environment variable FOO with value foo, and by preneding something to PATH.
On Linux, I would simply use os.exec*e to replace the Python process with a shell with the environment configured.
I tried the same approach on Windows (like os.exec*e(os.environ['ComSpec'])), but it doesn't work, the environment of the newly executed cmd is messed up like this:
Running just set doesn't list FOO and doesn't show the effect on PATH. Running set FOO, however, shows FOO=foo, and echo %FOO% echoes foo.
Running set PATH or echo %PATH% shows the modified PATH variable. Running set path or echo %path% shows the value without the modification (even though env. vars are normally case insensitive on Windows).
If I type exit, the conole remains hanging in some state not accepting input, until I hit Ctrl+C. After that, it apparently returns to the cmd which originally called setup.py.
So clearly, os.exec*e doesn't work for this scenario on Windows. Is there a different way to achieve what I want? Is there a combination of subprocess.Popen() flags which would enable me to exit the calling Python process and leave the called cmd runnig, ideally in the same console? Or would accessing CreateProcess through ctypes help?
If necessary, I would settle for launching a new console window and closing the old one, but I certainly can't afford having the old console window hang in frozen state, waiting for a newly created one to close.
There's a much simpler solution if it's acceptable to use a Windows batch file in addition to your script, since the batch file runs in the calling process, and can therefore modify its environment.
Given a file setup.bat, which looks like this...
#echo off
for /f "tokens=*" %%a in ('python setup.py') do %%a
...and a file setup.py which looks like this...
import os
print 'set FOO=foo'
print 'set PATH=%s;%s' % ('C:\\my_path_dir', os.environ['PATH'])
...and assuming python.exe in in the PATH, then calling setup.bat from the command line will set the environment variables in the calling process, while still allowing you to make the setup.py script as complicated as you like, as long as it prints the commands you want to execute to stdout.
Update based on comments
If your setup.py has multiple modes of operation, you could make the setup.bat a generic wrapper for it. Suppose instead setup.bat looks like this...
#echo off
if "%1" == "setenv" (
for /f "tokens=*" %%a in ('python setup.py %1') do %%a
) else (
python setup.py %*
)
...and setup.py looks like this...
import sys
import os
if len(sys.argv) > 1 and sys.argv[1] == 'setenv':
print 'set FOO=foo'
print 'set PATH=%s;%s' % ('C:\\my_path_dir', os.environ['PATH'])
else:
print "I'm gonna do something else with argv=%r" % sys.argv
...would that not suffice?
I have a batch file that's supposed to set PATH/PYTHON path variables and then invoke my python script (myscript.py), that's designed as an interactive console. I tried with the following:
#echo off
setlocal
if not defined PYTHONHOME (echo warning: PYTHONHOME environment variable is not defined. Using C:\Python24 by default.
SET PYTHONHOME=C:\Python24
if not exist "C:\Python24" ( echo warning: C:\Python24 does not exists. Please specify PYTHONHOME variable manually.))
color 1e
set PYTHONSTARTUP=%~dp0%myscript.py
set PYTHONPATH=%~dp0;%PYTHONPATH%
path %PYTHONHOME%;%PATH%
set PATHEXT=%PATHEXT%;.PY
cd %~dp0%
cmd.exe /k title Interactive Python Console 1.0
cls
%~dp0%myscript.py"
:done
endlocal
Before setting the colorpair (1e)for the console, I have appended directory containing myscript to path, python path and python24 is set as python home.
My problem is:
I am able to change the default font/background color of console, set the current window's title, but then neither cls (clearscreen) works, nor does my script is invoked. At the console, my pwd is script's directory. But when i enter 'python' at the prompt, myscript is invoked and I can see interactive console of my script.
Anything missing from batch, that would automatically clear off the console after setting color/title, and invoke myscript.py?
This doesn't really have anything to do with Python. cmd /k doesn't "set the window title", it starts a new command shell and leaves you in it, thus stopping your script midway through. Why don't you just do title My New Title? There's no need to use cmd.