I have looked at the suggested similar questions and whilst useful, do not actual match my problem and I'm still struggling.
I am using a batch file to run a series of python files, and one of these python scripts returns a variable to be used as an argument in a later script (it has to be exported to console because it is also used as a parameter in an executable.)
By batch file looks like this:
#echo off
#title AutoStats
set raw_dir ='raw_directory'
set today_dir ='today_directory'
set archive_dir='archive_directory'
set error_file='error_directory'
set DateEstate='dE'
set OTQ_File='OTQ_File'
cd C:\dev\OTQtxt
for /f "delims=" %%a in ('get_date.py') do set $date=%%a
python create_csv.py %$date% %raw_dir% %archive_dir% %error_file%
pause
The python script looks like this:
from sys import argv
date, raw_dir, today_dir, archive_dir, error_file = argv[1:]
print date
print raw_dir
print today_dir
print archive_dir
print error_file
The reason for using argv[1:] is because I don't want to use the script name as an argument
In the future it will obviously do more than this, this is just for testing whether I can get the arguments in.
The error is as the title states. This only occurs when running it from the batch file, if I run it from powershell and type in the arguments myself then it works.
I find it odd that when typing the arguments myself in powershell the script works fine, when using the parameters set in the .bat it returns an error.
Can anybody shed some light on why this might be. I've never used batch files until now so it might just be a simple mistake.
Whilst the problem pointed out by Ffisegydd was correct, the real mistake causing the problem to happen with a different number of argument was with with setting of parameters in the batch file.
for the first 2 set lines I added a space after the parameter name:
set today_dir ='today_directory'
should have been:
set today_dir='today_directory'
Related
I'll want to know how to call a function in vs code. I read the answer to similar questions, but they don't work:
def userInput(n):
return n*n
userInput(5)
And appends nothing
def Input(n):
return n*n
And in the terminal:
from file import *
from: can't read /var/mail/file
Can somebody help me?
You are doing everything correctly in the first picture. In order to call a function in python on vs code you first have to define the function, which you did by typing def userInput(n):. If you want to see the result of your function, you should not use return, you should use print instead. Return is a keyword- so when your computer reaches the return keyword it attempts to send that value from one point in your code to another. If you want to see the result of your code, typing print (n) would work better.
Your code should look like this:
def userInput(n):
print (n * n)
userInput(5)
The code would print the result 25
Your terminal is your general way to access your operating system, so you have to tell it that you want it to interpret your Python code first.
If you want to run the file you're typing in, you have to first know the location of that file. When you type ls in your terminal, does the name of your Python file show up? If not, hover over the tab in VSCode (it's close to the top of the editor) and see what path appears. Then in your terminal type cd (short for "change directory") and then the path that you saw, minus the <your filename here>.py bit. Type ls again, and you should see your Python file. Now you can type python <your filename here>.py to run it (provided you have Python installed).
You could also run the IDLE by just typing python in your terminal. This will allow you to write your code line-by-line and immediately evaluate it, but it's easier to write in VSCode and then run it with the method I described before.
I want to start my python script from a batch file. It requires four arguments, that are processed in the script through sys.argv[n].
These arguments are paths, that are varying from programme call to programme call. So how do I create a batch file, where you can transfer new arguments for the programme call everytime you run the code? I have learned Python for just one semester and am stuck with this problem.
Initially I have created a batchfile to test whether the code is even trying to be executed. Of course it ran an error due to the arguments missing. Then I tried to pass the arguments through the batchfile, which didn't work and gave me the error like before 'list index out of range':
set 1= path1
set 2= path2
set 3= path3
set 4= path4
"C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exe" "C:\repo\PythonProgramme.py" %1 %2 %3 %4
pause
I expected the code to run, but as already said, the aguments where not being passed. Can somebody help me fix this issue and maybe give me a hint, what to use for varying arguments (paths)?
You need to surround your variable name with % for it to work. You should read the documentation for set and maybe also this article about batch variables.
In the meantime the following should work.
set var1=path1
set var2=path2
set var3=path3
set var4=path4
"C:\[...]\python.exe" "C:\repo\PythonProgramme.py" %var1% %var2% %var3% %var4%
pause
The error you get is from your (unknown) python code.
While unusual you can set variable names with just numbers
BUT to reference these vars you need to enclose them in percent signs on both sides %1%
With %1..%4 you reference the command line args passed to the batch itself,
if nothing was passed, there are no args for python to process
spaces around the equal sign in a set become part of the variable name/content.
While variables names starting with a letter are preferable (as Jacques Gaudin suggests +1), you can try:
"C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exe" ^
"C:\repo\PythonProgramme.py" %1% %2% %3% %4%
or, if the Path'es set may contain spaces:
"C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exe" ^
"C:\repo\PythonProgramme.py" "%1%" "%2%" "%3%" "%4%"
I know a very similar question has already been asked but since none of the solutions posted there worked for my problem I try to make it replicable:
So I'm calling this script to merge some shapefiles (all files in one folder) like this:
shpfiles = 'shapefile_a.shp shapefile_b.shp'
subprocess.call(['python', 'shapemerger.py', '%s' % shpfiles])
I only get the Usage Instructions from the script so I cant determine what goes wrong. If i call the script directly in the terminal it works.
Any help is appreciated.
Every time a program is started, it receives a list of arguments it was invoked with. This is often called argv (v stands for vector, i.e. one-dimensional array). The program parses this list, extracts options, parameters, filenames, etc. depending on its own invocation syntax.
When working at the command line, the shell takes care of parsing the input line, starting new program or programs and passing them their argument list.
When a program is called from another program, the caller is responsible to provide the correct arguments. It could delegate this work to shell. The price for it is very high. There is substantial overhead and possibly a security risk! Avoid this approach whenever possible.
Finally to the question itself:
shpfiles = 'shapefile_a.shp shapefile_b.shp'
subprocess.call(['python', 'shapemerger.py', '%s' % shpfiles])
This will invoke python to run the script shapemerger.py with one argument shapefile_a.shp shapefile_b.shp. The script expects filenames and receives this one name. The file "shapefile_a.shp shapefile_b.shp" does not exist, but the script probably stops before attempting to access that file, because it expect 2 or more files to process.
The correct way is to pass every filename as one argument. Assuming shpfiles is a whitespace separated list:
subprocess.call(['python', 'shapemerger.py'] + shpfiles.split())
will generate a list with 4 items. It is important to understand that this approach will fail if there is a space in a filename.
I am trying to run a sort of application that utilises both Python and powershell scripts. I already wrote the Python script and powershell script, which are meant to work simultaneously but separate from each other. What I want to do is create a Python program that launches them both, is there a way? Thanks!
What I have right now, as part of a larger script, is:
import subprocess
autom = r"C:\Users\mrmostacho\Desktop\Robot\Autom.ps1","-ExecutionPolicy","Unrestricted"
powershell = r"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
subprocess.Popen("%s %s" % (powershell, autom,))
I think you don't want "-ExecutionPolicy","Unrestricted" as script arguments but instead want to set powershells execution policy to allow the execution of your script. Therefore you should pass those parameters before the actual Script.
Second: It's not enough, to pass the script as argument to powershell.exe (this way the script name is interpreted as Powershell command and one has to escape the name according to powershells quoting rules). Instead the Script name should be given after the -File parameter. From online documentation:
-File []
Runs the specified script in the local scope ("dot-sourced"), so that the functions and variables that the script creates are
available in the current session. Enter the script file path and any
parameters. File must be the last parameter in the command, because
all characters typed after the File parameter name are interpreted as
the script file path followed by the script parameters.
You can include the parameters of a script, and parameter values, in
the value of the File parameter. For example: -File .\Get-Script.ps1 -Domain Central
Typically, the switch parameters of a script are either included or
omitted. For example, the following command uses the All parameter of
the Get-Script.ps1 script file: -File .\Get-Script.ps1 -All
In rare cases, you might need to provide a Boolean value for a switch
parameter. To provide a Boolean value for a switch parameter in the
value of the File parameter, enclose the parameter name and value in
curly braces, such as the following: -File .\Get-Script.ps1 {-All:$False}.
Third: As cdarke already commented, it's better to use a list instead of a string as argument to Popen. This way one doesn't need to worry about the CommandLine parsing on Windows.
Altogether, this should be the way to go. (Tested with small test script.)
import subprocess
autom = r"C:\Users\mrmostacho\Desktop\Robot\Autom.ps1"
powershell = r"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
subprocess.Popen([powershell,"-ExecutionPolicy","Unrestricted","-File", autom])
If you need to pass arguments to the script, do it like this:
subprocess.Popen([powershell,"-ExecutionPolicy","Unrestricted","-File", autom, 'arg 1', 'arg 2'])
I am trying to use Python to run an executable (Windows 7) with parameters. I have been able to make the program run, but the amount of parameters I can use that will prove the Python script worked with parameters is limited. The best one is formatted like so:
-debugoutput debug.txt
I have tested this using a windows shortcut with an edited target and it works, it creates a debug output in the program directory.
Here is the code I am using:
import subprocess
args = [r"C:\Users\MyName\LevelEditor\LevelEditor.exe", "-debugoutput debug.txt"]
subprocess.call(args)
This does run the program, but the debug output is not created. I have tried putting an "r" in front of the parameter but this made no difference. I assume it is a simple formatting error but I can't find any examples to learn from that are doing the same thing.
UPDATE:
Thanks for the answers everyone, all the same, simple formatting error indeed.
In-code definition results in invocation of shell command line:
C:\Users\MyName\LevelEditor\LevelEditor.exe "-debugoutput debug.txt"
As you can see, by merging -debugoutput debug.txt to single list element, you explicitly stated that space between them shouldn't be parsed as command line argument separator.
To achieve expected behavior put file name string as separate element to argument list.
[r"C:\Users\MyName\LevelEditor\LevelEditor.exe", "-debugoutput", "debug.txt"]
As far as I know you need to split the arguments by the space, so your args would look like:
args = [r"C:\Users\MyName\LevelEditor\LevelEditor.exe", "-debugoutput", "debug.txt"]
Does that work?
I do not know if it works, but
import subprocess
args = [r"C:\Users\MyName\LevelEditor\LevelEditor.exe", "-debugoutput", "debug.txt"]
subprocess.run(args)
Following the docs