I'm trying to run this script using the code
subprocess.call(["php C:\Python27\a.php"])
and I'm getting this error:
FileNotFoundError: [WinError 2] The system cannot find the file specified
i have tried changing path but nothing seems to work, any ideas?
Either
subprocess.call(["php", "C:\\Python27\\a.php"])
or
subprocess.call(["php", r"C:\Python27\a.php"])
should work.
Try this:
subprocess.call(["php", "C:\\Python27\\a.php"])
From the documentation:
args is required for all calls and should be a string, or a sequence
of program arguments. Providing a sequence of arguments is generally
preferred, as it allows the module to take care of any required
escaping and quoting of arguments (e.g. to permit spaces in file
names). If passing a single string, either shell must be True (see
below) or else the string must simply name the program to be executed
without specifying any arguments.
Also note that in python, like many other languages, the backslash in a normal string has special meaning. You'll have to use double backslashes or a raw string to get the behavior you want.
Related
I am using Raspberry Pi to record audio. I tried pyaudio but it didn't work, then I tried to use the subprocess module. As the recording needs to be executed multiple times, I need to make sure that the recoding filename is different after every recording.
For example, I would like to:
filename = datetime.now().strftime("%Y-%m-%d_%H_%M_%S")+".wav"
My question is: can I pass this filename as an argument to subprocess? I checked the document, it says only string and list are supported as arguments in subprocess.
This filename is a string. So nothing prevents it from being used as one of the strings in subprocess.
Take care to use the list of strings variant with shell=False (the default) and the string variant with shell=True. Then everything should work as needed.
I am attempting to pass in a string as input argument to a Python program, from the command line i.e. $python parser_prog.py <pos1> <pos2> --opt1 --opt2 and interpreting these using argparse. Of course if contains any metacharacters these are first interpreted by the shell, so it needs to be quoted.
This seems to work, strings are passed through literally, preserving the \*?! characters:
$ python parser_prog.py 'str\1*?' 'str2!'
However, when I attempt to pass through a '-' (hyphen) character, I cannot seem to mask it. It is interpreted as an invalid option.
$ python parser_prog.py 'str\1*?' '-str2!'
I have tried single and double quotes, is there a way to make sure Python interprets this as a raw string? (I'm not in the interpreter yet, this is on the shell command line, so I can't use pythonic expressions such as r'str1')
Thank you for any hints!
As you said yourself, Python only sees the strings after being processed by the shell. The command-line arguments '-f' and -f look identical to the called program, and there is no way to dsitinguish them. That said, I think that argparse supports a -- argument to denote the end of the options, and everything after this is treated as a positional argument.
I am quite new to python and i struck an issue wherein, I am dynamically retrieving a string from a dictionary which looks like this
files="eputilities/epbalancing_alb/referenced assemblies/model/cv6_xmltypemodel_xp2.cs"
I am unable to to perform any actions on this particular file as it is reading the path as 2 different strings
eputilities/epbalancing_alb/referenced and assemblies/model/cv6_xmltypemodel_xp2.cs
as there is a space between referenced and assemblies.
I wanted to know how to convert this to raw_string (ignore the space, but still keep the space between the two and consider it as one string)
I'm not able to figure this out although several comments where there on the web.
Please do help.
Thanks
From the comments to the other answer, I understand that you want to execute some external tool and pass a parameter (a filename) to it. This parameter, however, has spaces in it.
I'd propose to approaches; definitely, I'd use subprocess, not os.system.
import subprocess
# Option 1
subprocess.call([path_to_executable, parameter])
# Option 2
subprocess.call("%s \"%s\"" % (path_to_executable, parameter), shell=True)
For me, both worked, please check if they work yor you as well.
Explanations:
Option 1 takes a list of strings, where the first string has to be the path to the executable and all others are interpreted as command line arguments. As subprocess.call knows about each of these entities, it properly calls the external so that it understand thatparameter` is to be interpreted as one string with spaces - and not as two or more parameters.
Option 2 is different. With the keyword-argument shell=True we tell subprocess.call to execute the call through a shell, i.e., the first positional argument is "interpreted as if it was typed like this in a shell". But now, we have to prepare this string accordingly. So what would you do if you had to type a filename with spaces as a parameter? You'd put it between double quotes. This is what I do here.
Standard string building in python works like this
'%s foo %s'%(str_val_1, str_val_2)
So if I'm understanding you right either have a list of two strings or two different string variables.
For the prior do this:
' '.join(list)
For the latter do this:
'%s %s'%(string_1, string_2)
I am calling a python script through a bash wrapper, but I'm having trouble dealing with arguments that contain quoted spaces.
I assemble the arguments to the python script into a bash variable, such as
opt="-c start.txt"
opt+="--self 'name Na'"
Then call the python script with something like:
python test_args.py $opt
When printing sys.argv in Python, I get
['test-args.py', '-c', 'start.txt', '--self', "'name", "Na'"]
instead of the expected
['test-args.py', '-c', 'start.txt', '--self', 'name Na']
I tried using an array when calling the script, such as
python test_args.py ${opt[#]}
but then I get
['test-args.py', "-c start.txt --self 'name Na'"]
Any other ideas?
Use an array, but store each argument as a separate element in the array:
opt=(-c start.txt)
opt+=(--self 'name Na')
python test_args.py "${opt[#]}"
See BashFAQ #050.
This is what the shlex module is for.
The shlex class makes it easy to write lexical analyzers for simple
syntaxes resembling that of the Unix shell. This will often be useful
for writing minilanguages, (for example, in run control files for
Python applications) or for parsing quoted strings.
Your instinct to embed spaces inside the variable's value was good, but when the value is simply expanded during the command line parsing their special meaning is lost as you saw. You need to expand the variable before the command line to your python script is parsed:
set -f
eval python test_args.py $opt
set +f
That will expand to:
python test_args.py -c start.txt --self 'name Na'
Which will then be parsed correctly with the quotes regaining their special meaning.
Edit: I've added set -f/+f (aka -/+o noglob) around the eval to disable file globbing although that wasn't an issue in the OP's example that's not an unheard of issue with eval. (Another, stronger caveat is to never eval user input unless you take extreme care to make sure it won't blow up into something nasty. If you don't control the value being eval-ed, you can't be sure what will happen.)
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Full command line as it was typed
sys.argv is already a parsed array, losing double quotes, double spaces and maybe even tab characters (it all depends on the OS/shell, of course).
How can I access the original string before parsing?
Shortly, you don't.
Long: on Unix command line is parsed by the calling program and by the time python starts you already have the command line parsed.
PS. On Windows it is possible, but I suppose you are looking for a general response.
You can't do that explicitly because, this is how a shell passes the arguments to a program.
The sys.argv is all Python got. The shell processed the filename generation (globs), parameter (variable) expansion, quotes, and word splitting before passing the arguments to the Python process (in Unix; in Windows it's the startup actually parsing it, but for portability, you can't rely on that).
However, remember that POSIX shell quoting rules allow passing any characters you may want (except NUL bytes that terminate strings).
Compare starting a process from Python using subprocess.call with or without the shell argument set. With shell=False the list of strings is what comes up in the sys.argv in the started process (starting with the script path; parameters processed by Python itself are removed) while with shell=True the string is passed to the shell which interprets it according to its own rules.