python argparse how to get entire command as string - python

I have a script named patchWidth.py and it parses command line arguments with argparse:
# read command line arguments -- the code is able to process multiple files
parser = argparse.ArgumentParser(description='angle simulation trajectories')
parser.add_argument('filenames', metavar='filename', type=str, nargs='+')
parser.add_argument('-vec', metavar='v', type=float, nargs=3)
Suppose this script is run with the following:
>>> python patchWidth.py file.dat -vec 0. 0. 1.
Is there a way to get this entire thing as a string in python? I would like to be able to print to the output file what command was run with what arguments.

Yes, you can use the sys module:
import sys
str(sys.argv) # arguments as string
Note that argv[0] is the script name. For more information, take a look at the sys module documentation.

I do not know if it would be the best option, but...
import sys
" ".join(sys.argv)
Will return a string like /the/path/of/file/my_file.py arg1 arg2 arg3

This will work with commands that have space-separated strings in them.
import sys
" ".join("\""+arg+"\"" if " " in arg else arg for arg in sys.argv)
Sample output:
$ python3 /tmp/derp.py "my arg" 1 2 3
python3 /tmp/derp.py "my arg" 1 2 3
This won't work if there's a string argument with a quotation mark in it, to get around that you'd have to delimit the quotes like: arg.replace("\"", "\\\""). I left it out for brevity.

Related

Python how to parse the string after the python3 hello.py getThisString [duplicate]

I use python to create my project settings setup, but I need help getting the command line arguments.
I tried this on the terminal:
$python myfile.py var1 var2 var3
In my Python file, I want to use all variables that are input.
Python tutorial explains it:
import sys
print(sys.argv)
More specifically, if you run python example.py one two three:
>>> import sys
>>> print(sys.argv)
['example.py', 'one', 'two', 'three']
To get only the command line arguments
(not including the name of the Python file)
import sys
sys.argv[1:]
The [1:] is a slice starting from the second element (index 1) and going to the end of the arguments list. This is because the first element is the name of the Python file, and we want to remove that.
I highly recommend argparse which comes with Python 2.7 and later.
The argparse module reduces boiler plate code and makes your code more robust, because the module handles all standard use cases (including subcommands), generates the help and usage for you, checks and sanitize the user input - all stuff you have to worry about when you are using sys.argv approach. And it is for free (built-in).
Here a small example:
import argparse
parser = argparse.ArgumentParser("simple_example")
parser.add_argument("counter", help="An integer will be increased by 1 and printed.", type=int)
args = parser.parse_args()
print(args.counter + 1)
and the output for python prog.py -h
usage: simple_example [-h] counter
positional arguments:
counter counter will be increased by 1 and printed.
optional arguments:
-h, --help show this help message and exit
and the output for python prog.py 1 As one would expect:
2
Python code:
import sys
# main
param_1= sys.argv[1]
param_2= sys.argv[2]
param_3= sys.argv[3]
print 'Params=', param_1, param_2, param_3
Invocation:
$python myfile.py var1 var2 var3
Output:
Params= var1 var2 var3
You can use sys.argv to get the arguments as a list.
If you need to access individual elements, you can use
sys.argv[i]
where i is index, 0 will give you the python filename being executed. Any index after that are the arguments passed.
You can access arguments by key using "argparse".
Let's say that we have this command:
python main.py --product_id 1001028
To access the argument product_id, we need to declare it first and then get it:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--product_id', dest='product_id', type=str, help='Add product_id')
args = parser.parse_args()
print (args.product_id)
Output:
1001028
If you call it like this: $ python myfile.py var1 var2 var3
import sys
var1 = sys.argv[1]
var2 = sys.argv[2]
var3 = sys.argv[3]
Similar to arrays you also have sys.argv[0] which is always the current working directory.
Some additional things that I can think of.
As #allsyed said sys.argv gives a list of components (including program name), so if you want to know the number of elements passed through command line you can use len() to determine it. Based on this, you can design exception/error messages if user didn't pass specific number of parameters.
Also if you looking for a better way to handle command line arguments, I would suggest you look at https://docs.python.org/2/howto/argparse.html
First, You will need to import sys
sys - System-specific parameters and functions
This module provides access to certain variables used and maintained by the interpreter, and to functions that interact strongly with the interpreter. This module is still available. I will edit this post in case this module is not working anymore.
And then, you can print the numbers of arguments or what you want here, the list of arguments.
Follow the script below :
#!/usr/bin/python
import sys
print 'Number of arguments entered :' len(sys.argv)
print 'Your argument list :' str(sys.argv)
Then, run your python script :
$ python arguments_List.py chocolate milk hot_Chocolate
And you will have the result that you were asking :
Number of arguments entered : 4
Your argument list : ['arguments_List.py', 'chocolate', 'milk', 'hot_Chocolate']
Hope that helped someone.
should use of sys ( system ) module .
the arguments has str type and are in an array
NOTICE : argv is not function or class and is variable & can change
NOTICE : argv[0] is file name
NOTICE : because python written in c , C have main(int argc , char *argv[]); but argc in sys module does not exits
NOTICE : sys module is named System and written in C that NOT A SOURCE BASED MODULE
from sys import argv # or
from sys import * # or
import sys
# code
print("is list") if type(sys.argv) == list else pass # is list ,or
print("is list") if type(argv) == list else pass # is list
# arguments are str ( string )
print(type(sys.argv[1])) # str
# command : python filename.py 1 2 3
print(len(sys.argv)) # 3
print(sys.argv[1],'\n',sys.argv[2]'\n',sys.argv[3]) # following
'''
1
2
3
'''
# command : python filename.py 123
print(len(sys.argv)) # 1
print(sys.argv[1]) # following
'''
123
'''
Using the following code, you can check whether the arguments are entered. If it is the case, the arguments are printed; otherwise, a message stating that the arguments are not entered is printed.
import sys
if len(sys.args) <= 1:
print("the arguments are not entered in the command line")
else:
for arg in args:
print(arg)

Python script : Running a script with multiple arguments using subprocess

My question is related to this earlier question - Python subprocess usage
I am trying to run this command using python
nccopy -k 4 "http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2/pressure/air.2014.nc?air[408:603][2][20:34][26:40]" foo.nc
When I run the above command I should be able to see a file called foo.nc on my disk or a network error stating unable to access that URL or remote URL not found.
Currently the ESRL NOAA server is down - so when I run the above command I get
syntax error, unexpected $end, expecting SCAN_ATTR or SCAN_DATASET or SCAN_ERROR
context: ^
NetCDF: Access failure
Location: file nccopy.c; line 1348
I should get the same error when I run the python script
This is the code I have and I am unable to figure out exactly how to proceed further -
I tried splitting up "-k 4" into two arguments and removing the quotes and I still get this error nccopy : invalid format : 4
Results of print(sys.argv) data.py
['data.py', '-k', '4', 'http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2/pressure/air.2014.nc?air[480:603][20:34][26:40]', 'foo.nc']
import numpy as np
import subprocess
import sys
url = '"http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2/pressure/air.2014.nc?air[408:603][2][20:34][26:40]"'
outputFile = 'foo.nc'
arg1 = "-k 4"
arg3 = url
arg4 = outputFile
print (input)
subprocess.check_call(["nccopy",arg1,arg3,arg4])
There's two dilemmas here.
One being that subprocess processes your arguments and tries to use 4 as a separate argument.
The other being that system calls still goes under normal shell rules, meaning that parameters and commands will be parsed for metacharacters aka special characters. In this case you're wrapping [ and ].
There for you need to separate each parameters and it's value into separate objects in the parameter-list, for instance -k 4 should be ['-k', '4'] and you need to wrap parameters/values in '...' instead of "...".
Try this, shlex.split() does the grunt work for you, and i swapped the encapsulation characters around the URL:
import numpy as np
import subprocess
import sys
import shlex
url = "'http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2/pressure/air.2014.nc?air[408:603][2][20:34][26:40]'"
outputFile = 'foo.nc'
command_list = shlex.split('nccopy -k 4 ' + url + ' ' + outpufFile)
print(command_list)
subprocess.check_call(command_list)
Instead of arg1 = "-k 4", use two arguments instead.
import subprocess
url = 'http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2/pressure/air.2014.nc?air[408:603][2][20:34][26:40]'
outputFile = 'foo.nc'
arg1 = "-k"
arg2 = "4"
arg3 = url
arg4 = outputFile
subprocess.check_call(["nccopy", arg1, arg2, arg3, arg4])
See also here Python subprocess arguments
If you have a working shell command that runs a single program with multiple arguments and you want to parameterized it e.g., to use a variable filename instead of the hardcoded value then you could use shlex.split() to create a list of command-line arguments that you could pass to subprocess module and replace the desired argument with a variable e.g.:
>>> shell_command = "python -c 'import sys; print(sys.argv)' 1 't w o'"
>>> import shlex
>>> shlex.split(shell_command)
['python', '-c', 'import sys; print(sys.argv)', '1', 't w o']
To run the command using the same Python interpreter as the parent script, sys.executable could be used and we can pass a variable instead of '1':
#!/usr/bin/env python
import random
import sys
import subprocess
variable = random.choice('ab')
subprocess.check_call([sys.executable, '-c', 'import sys; print(sys.argv)',
variable, 't w o'])
Note:
one command-line argument per list item
no shlex.split() in the final code
there are no quotes inside 't w o' i.e., 't w o' is used instead of '"t w o"' or "'t w o'"
subprocess module does not run the shell by default and therefore you don't need to escape shell meta-characters such as a space inside the command-line arguments. And in reverse, if your command uses some shell functionality (e.g., file patterns) then either reimplement the corresponding features in Python (e.g., using glob module) or use shell=True and pass the command as a string as is. You might need pipes.quote(), to escape variable arguments in this case. Wildcard not working in subprocess call using shlex

Passing Strings as Python command-line arguments

I’m able to pass ints and chars as Python command-line args, but can’t pass Strings successfully to the following:
if __name__ == '__main__' :
try :
print(len(sys.argv))
arg1 = ast.literal_eval(sys.argv[1])
arg2 = ast.literal_eval(sys.argv[2])
print(arg1)
print(arg2)
except Exception :
print('error')
The following works:
python test.py 1 2
and prints:
3
1
2
as dos the following:
python test.py ‘1’ ‘2’
which also prints
3
1
2
However, the following does not work:
python test.py ‘one’ ‘two’
It sees the number of args, but throws an Exception trying to grab them:
3
error
Could someone please provide some guidance on how to pass Strings as command-line args?
Thanks.
Your shell will eat those quotes before python ever sees them. Try like this:
python test.py '"one"' '"two"'
As an aside, command-line args are passed as strings anyway. It is odd to literal_eval them like this; a better pattern is to convert the strings to numbers when you need the numbers, and to just leave them as strings otherwise. This will also save you from having to quote-pad the strings twice on the command line.
The argparse module can handle that stuff for you automatically.
optparse.OptionParser may be helpful for you.
You can use it like this:
from optparse import OptionParser
if __name__ == "__main__":
parser = OptionParser(version="%prog 1.0.0")
parser.add_option("-c", "--config", action="store", dest="config_file",
default="test", type="string",
help="let prog load a specified configure file")
parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
default=False, help="let prog run in verbose model")
options, args = parser.parse_args()
if options.verbose:
print "run in verbose model"
print "configure file is %s"%(options.config_file)

How do I access command line arguments?

I use python to create my project settings setup, but I need help getting the command line arguments.
I tried this on the terminal:
$python myfile.py var1 var2 var3
In my Python file, I want to use all variables that are input.
Python tutorial explains it:
import sys
print(sys.argv)
More specifically, if you run python example.py one two three:
>>> import sys
>>> print(sys.argv)
['example.py', 'one', 'two', 'three']
To get only the command line arguments
(not including the name of the Python file)
import sys
sys.argv[1:]
The [1:] is a slice starting from the second element (index 1) and going to the end of the arguments list. This is because the first element is the name of the Python file, and we want to remove that.
I highly recommend argparse which comes with Python 2.7 and later.
The argparse module reduces boiler plate code and makes your code more robust, because the module handles all standard use cases (including subcommands), generates the help and usage for you, checks and sanitize the user input - all stuff you have to worry about when you are using sys.argv approach. And it is for free (built-in).
Here a small example:
import argparse
parser = argparse.ArgumentParser("simple_example")
parser.add_argument("counter", help="An integer will be increased by 1 and printed.", type=int)
args = parser.parse_args()
print(args.counter + 1)
and the output for python prog.py -h
usage: simple_example [-h] counter
positional arguments:
counter counter will be increased by 1 and printed.
optional arguments:
-h, --help show this help message and exit
and the output for python prog.py 1 As one would expect:
2
Python code:
import sys
# main
param_1= sys.argv[1]
param_2= sys.argv[2]
param_3= sys.argv[3]
print 'Params=', param_1, param_2, param_3
Invocation:
$python myfile.py var1 var2 var3
Output:
Params= var1 var2 var3
You can use sys.argv to get the arguments as a list.
If you need to access individual elements, you can use
sys.argv[i]
where i is index, 0 will give you the python filename being executed. Any index after that are the arguments passed.
You can access arguments by key using "argparse".
Let's say that we have this command:
python main.py --product_id 1001028
To access the argument product_id, we need to declare it first and then get it:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--product_id', dest='product_id', type=str, help='Add product_id')
args = parser.parse_args()
print (args.product_id)
Output:
1001028
If you call it like this: $ python myfile.py var1 var2 var3
import sys
var1 = sys.argv[1]
var2 = sys.argv[2]
var3 = sys.argv[3]
Similar to arrays you also have sys.argv[0] which is always the current working directory.
Some additional things that I can think of.
As #allsyed said sys.argv gives a list of components (including program name), so if you want to know the number of elements passed through command line you can use len() to determine it. Based on this, you can design exception/error messages if user didn't pass specific number of parameters.
Also if you looking for a better way to handle command line arguments, I would suggest you look at https://docs.python.org/2/howto/argparse.html
First, You will need to import sys
sys - System-specific parameters and functions
This module provides access to certain variables used and maintained by the interpreter, and to functions that interact strongly with the interpreter. This module is still available. I will edit this post in case this module is not working anymore.
And then, you can print the numbers of arguments or what you want here, the list of arguments.
Follow the script below :
#!/usr/bin/python
import sys
print 'Number of arguments entered :' len(sys.argv)
print 'Your argument list :' str(sys.argv)
Then, run your python script :
$ python arguments_List.py chocolate milk hot_Chocolate
And you will have the result that you were asking :
Number of arguments entered : 4
Your argument list : ['arguments_List.py', 'chocolate', 'milk', 'hot_Chocolate']
Hope that helped someone.
should use of sys ( system ) module .
the arguments has str type and are in an array
NOTICE : argv is not function or class and is variable & can change
NOTICE : argv[0] is file name
NOTICE : because python written in c , C have main(int argc , char *argv[]); but argc in sys module does not exits
NOTICE : sys module is named System and written in C that NOT A SOURCE BASED MODULE
from sys import argv # or
from sys import * # or
import sys
# code
print("is list") if type(sys.argv) == list else pass # is list ,or
print("is list") if type(argv) == list else pass # is list
# arguments are str ( string )
print(type(sys.argv[1])) # str
# command : python filename.py 1 2 3
print(len(sys.argv)) # 3
print(sys.argv[1],'\n',sys.argv[2]'\n',sys.argv[3]) # following
'''
1
2
3
'''
# command : python filename.py 123
print(len(sys.argv)) # 1
print(sys.argv[1]) # following
'''
123
'''
Using the following code, you can check whether the arguments are entered. If it is the case, the arguments are printed; otherwise, a message stating that the arguments are not entered is printed.
import sys
if len(sys.args) <= 1:
print("the arguments are not entered in the command line")
else:
for arg in args:
print(arg)

How do I make a command line program that takes arguments?

How can I make a command line, so I can execute my program on Windows with some parameters...
For example:
C:/Program/App.exe -safemode
have a look at the getopt and optparse modules from the standard lib, many good things could be also said about more advanced argparse module.
Generally you just need to access sys.argv.
I sense that you also want to generate an 'executable' that you can run standalone.... For that you use py2exe
Here is a complete example.py:
import optparse
parser = optparse.OptionParser()
parser.add_option("-s", "--safemode",
default = False,
action = "store_true",
help = "Should program run in safe mode?")
parser.add_option("-w", "--width",
type = "int",
default = 1024,
help = "Desired screen width in pixels")
options, arguments = parser.parse_args()
if options.safemode:
print "Proceeding safely"
else:
print "Proceeding dangerously"
if options.width == 1024:
print "running in 1024-pixel mode"
elif options.width == 1920:
print "running in 1920-pixel mode"
And here is a complete setup.py that will turn the above example.py into example.exe (in the dist subdirectory):
from distutils.core import setup
import py2exe
import sys
sys.argv.append('py2exe')
setup(
options = {'py2exe': dict(bundle_files=1, optimize=2)},
console = ["example.py"],
zipfile = None,
)
Are you speaking about parameter passed to a python script?
'couse you can access them by
import sys
print sys.argv
Or can use a more sophisticated getopt module.
Not a python guy (yet anyway) but my Google-fu found this assuming you meant "handling command line arguments":
http://www.faqs.org/docs/diveintopython/kgp_commandline.html
Use optparse.OptionParser.
from optparse import OptionParser
import sys
def make_cli_parser():
"""Makes the parser for the command line interface."""
usage = "python %prog [OPTIONS]"
cli_parser = OptionParser(usage)
cli_parser.add_option('-s', '--safemode', action='store_true',
help="Run in safe mode")
return cli_parser
def main(argv):
cli_parser = make_cli_parser()
opts, args = cli_parser.parse_args(argv)
if opts.safemode:
print "Running in safe mode."
else:
print "Running with the devil."
if __name__ == '__main__':
main(sys.argv[1:])
In use:
$ python opt.py
Running with the devil.
$ python opt.py -s
Running in safe mode.
$ python opt.py -h
Usage: python opt.py [OPTIONS]
Options:
-h, --help show this help message and exit
-s, --safemode Run in safe mode
Or are you just asking how to open a command line?
go to the start menu, click "run" (or just type, in Windows 7), type "cmd"
This will open up a command shell.
Given that your question is tagged python, I'm not sure it's going to be compiled into an exe, you might have to type "python (your source here).py -safemode".
The other comments addressed how to handle parameters. If you want to make your python program an exe you might want to look at py2exe.
This is not required but you mentioned App.exe and not App.py
You are asking a question that has several levels of answers.
First, command line is passed into the array sys.argv. argv is a historic name from C and Unix languages. So:
~/p$ cat > args.py
import sys
print "You have ", len(sys.argv), "arguments."
for i in range(len(sys.argv)):
print "argv[", i, "] = ", sys.argv[i]
~/p$ python args.py 34 2 2 2
You have 5 arguments.
argv[ 0 ] = args.py
argv[ 1 ] = 34
argv[ 2 ] = 2
argv[ 3 ] = 2
argv[ 4 ] = 2
This works both in MS Windows and Unix.
Second, you might be asking "How do I get nice arguments? Have it handle /help in
MS Windows or --help in Linux?"
Well, there are three choices which try to do what you want. Two, optparse and getopt are already in the standard library, while argparse is on its way. All three of these are libraries that start with the sys.argv array of strings, a description of you command line arguments, and return some sort of data structure or class from which
you can get the options you mean.
getopt does the minimal job. It does not provide "/help" or "--help".
optparse does a more detailed job. It provides "/help" and both short and long
versions of options, e.g., "-v" and "--verbose".
argparse handles the kitchen sink, including "/help", short and long commands,
and also subcommand structures, as you see in source control "git add ....", and
positional arguments.
As you move to the richer parsing, you need to give the parser more details about what you want the command line arguments to be. For example, you need to pass a long written
description of the argument if you want the --help argument to print it.
Third, you might be asking for a tool that just deals with the options from the command
line, environment variables and configuration files. Python currently has separate tools
for each of these. Perhaps I'll write a unified one, You will need:
- Command line arguments parsed by argparse, or getopt, etc.
- Environment variables, from os.environ[]
- Configuration files from ConfigFile or plistlib, etc.
and build your own answer to "what are the settings"?
Hope this fully answers your questions
One of the many ways:
import sys
print sys.argv
>>>python arg.py arg1 arg2
['arg.py', 'arg1', 'arg2']
sys.argv is a list containing all the arguments (also the name of script/program) as string.

Categories