My main script, main.py runs in python3. within it, I want to launch another script in some specified version of python.
import subprocess
pysh="/data/data/org.qpython.qpy/files/bin/qpython-android5.sh"
subprocess.call([pysh,'filetext.py'])
Question:
How can I use subprocess to open filetext.py in python2.x or 3.x interchangeably?
I have tried:
I have tried inputting several different arguments to no avail, such as:
os.system('python -2 -m filetext.txt')
or
subprocess.call(['py -2 filetext.txt'])
or
subprocess.call(['C:/Python27/python.exe filetext.txt'])
Any help would be immensely appreciated.
When I try almost the same thing, it seems to work as follows:
import subprocess
print(subprocess.call(["python2", "-c", "import sys; print sys.version"]))
When called from python3 this prints 2.7.5. This will depend of course on if the version of python you want to use is on the PATH, and if not, calling the binary with the full path.
Not sure if it's just a typo here, but I notice you said you wanted to run filetext.py, but you're passing filetext.txt in your examples.
If this doesn't work, I'd have to know more -- you say it doesn't work, but what exactly happens?
Try this :
subprocess.call(['C:/Python27/python.exe', "filetext.txt"])
First you give the path to the executable you need, then the arguments in a different parameter.
Related
(Asking a question in order to answer it, having been initially puzzled by this. Other answers obviously welcome.)
Using #!/usr/bin/env python is a common trick to allow the python interpreter to be found using a PATH lookup, rather than hard-coding the path to python. It could be convenient to be adapt this to add a PATH=... argument to env, in order to hard-code a list of candidate directories while not hard-coding a single exact path. (This would make use of the fact that env uses the specified PATH variable when locating python, aside from passing it to the python process.)
For example (in test.py):
#!/usr/bin/env PATH=/opt/python/bin:/usr/bin:/bin python
import sys
print(sys.executable) # show which executable it found
But if you try this, although the command works if executed explicitly from the shell command line:
$ echo $PATH
/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ /usr/bin/env PATH=/opt/python/bin:/usr/bin:/bin python ./test.py
/opt/python/bin/python
it fails when trying to run it via the shebang:
$ ./test.py
[hangs - infinite loop]
Why is this, and what can be done instead?
Regarding why it fails, it turns out that this is an example of the problem described here.
As regards what can be done about it, it is possible to adapt various this workaround to a similar problem, namely how to pass an argument to python in #!/usr/bin/env python (which although it is not exactly the same problem, also relates to wanting to have more than two items in the shebang line).
This gives:
#!/bin/sh
''''export PATH=/opt/python/bin:/usr/bin:/bin; exec python "$0" # '''
import sys
print(sys.executable)
Invoking it via the shebang, we get:
$ ./test.py
/opt/python/bin/python
Solutions involving #!/usr/bin/env -S PATH=... python (GNU coreutils >= 8.30) still appear not to be sufficiently portable (e.g. Ubuntu 18.04.4, which was the latest LTS release until April 2020, has coreutils 8.28).
i am using python 2.7.x
I automating my stuffs and in there i need run to another python program from my python script for that i am using the system function from the 'os' library.
for e.g:
import os
os.system("python anotherscript.py --data <USER_INPUT_FROM_MY_SCRIPT_HERE>")
so i know if any user inputs some other command in place of expected user input that will be converting to os command injection and that's what i want prevent in this case.
Thank you.
Since you need to run a Python script from Python, just import it the Python way and invoke the needed function normally
import anotherscript
anotherscript.<function>("<user_input>")
#Tenchi2xh's answer is the better way to do it, but if that doesn't work (e.g. your script only works on Python 2.x and the other one only works on Python 3.x) then you should use the subprocess module, passing the arguments as a list:
import subprocess
subprocess.call(['python', 'anotherscript.py', '--data', '<USER INPUT>'])
Also take a look at subprocess.check_call and subprocess.check_output to see if they are closer to what you need.
https://docs.python.org/2/library/subprocess.html#subprocess.call
My environment uses Python 2.6 and I'm new to Python. I need to write a script that runs a file decoding command which takes several arguments from the command line. My problem is I can't parse arguments taken from the terminal to the file decoding command.
For example if my program name is x.py and when i run "x.py Desktop/abc.txt" how can i pass Desktop/abc.txt as an argument to the cat command?
import commands
import sys
a=open("b.txt","w")
a.write(commands.getoutput('cat sys.argv[1]'))
When i researched it seemed that the above program should work but it didn't. Please help.
You should change commands.getoutput('cat sys.argv[1]') as commands.getoutput('cat %s' % (sys.argv[1],))
You're mixing up the terminal commands and Python commands. If you have a file called abc.py with the following code:
import sys
print sys.argv[1]
And you run it with python abc.py arg1, it should print out arg1.
For a cleaner and easier to read way of using command-line arguments if you want to control things like make sure they are int or allow multiple or whatever, I've had a lot of success using the argparse module in Python - it's much easier to use than the sys.argv style of parsing command-line arguments. Check out the official tutorial / docs here: https://docs.python.org/2/howto/argparse.html
I want my program to open iTunes during runtime. How do I implement this ?
I looked around for answers but didn't get any concrete complete answers. Till now, all I know is I could use the os module and then call the os.system() function to open iTunes. If this is right, what goes into the brackets ?
I have a Mac OS X machine.
One straightforward way to do this on Mac OS X will be to use the open command:
os.system("open -a iTunes")
There are undoubtedly other ways of doing this (e.g, using the Cocoa/Python bridge), but this is the simplest.
This should be able to help you.
From the article linked above...
import sys, string, os, arcgisscripting
os.chdir( 'c:\\documents and settings\\flow_model' )
os.system( '"C:\\Documents and Settings\\flow_model\\flow.exe"' )
Use subprocess.call() if you want to simply run an executable.
os.system() run the command in a subshell, which generates an unnecessary extra process and slightly different behavior depending on the operating system/console used (for example cmd.exe have different escaping than bash)
Read subprocess, is better than os.system in your case.
Subprocess module: http://docs.python.org/2/library/subprocess.html
I want to run both cProfiler (For time measurement, mainly) and also a memory profiler that I found here. However, both require the -m command line argument to be given, which doesn't exactly play nicely.
Is there a way to have both running? All I've managed to do so far is get the interpreter yelling at me.
If you need any more information, let me know and I'll do my best to provide it. Thanks in advance!
It is not possible to start two modules using two -m arguments. This is because the command line arguments after -m are all given to the named module as sys.argv. This is not described explicitly in the documentation but you can try it out experimentally.
Create two python files a.py and b.py.
Contents of a.py:
print 'a'
import sys
print sys.argv
Contents of b.py:
print 'b'
Now try to run both using two -m arguments:
$ python -m a -m b
Output:
a
['/home/lesmana/tmp/a.py', '-m', 'b']
As you can see module b is never started because the second -m is not handled by python. It is given to module a to handle.
While it's now evident to me that you can't use two -m arguments on the same file, I managed to pull together something of a solution. It's a bit round-about, and not exactly perfect, though.
I used 2 .bat files, which can be seen here. On the left hand side is the .bat that handles cProfiler, and on the right is the .bat that handles the memory profiler.
The code for the python programs seen in the .bat handling the memory profiler can be seen here and here.
The first program adds # to the line directly above the function in my main code here, which means that the program can actually run, and cProfiler can do its thing.
The second program removes that #, meaning that the memory profiler can work.
For this system to work properly with my layout, the "#profile" needs to be commented out in the first place.
It's a bit kludgey, and could use some refinement to automate it further (Such as having to specify the name of the file in the .bat file handling the memory profiler), but it'll do for now. I also realize that it's quite a specific case, but who knows, maybe someone is in the exact same position as I was...