I want to run a python script from another python code in Windows. For this I am using "subprocess" module. Below are sample 2 python scripts.
app.py is as below,
#!/usr/bin/env python3
import subprocess
command = "python"
filename = "test.py"
args=[]
args.append(command)
args.append(filename)
output = subprocess.run(args)
and test.py is
import time
print("hello")
time.sleep(10)
When I run app.py, from subprocess test.py also runs. In ubuntu for both app.py and test.py separate PID s will be there.
But in Windows, I get PID of app.py but not of test.py.
I checked this command,
tasklist /v | FIND "test.py"
This gives empty result.
Can anybody help,
What should I do, so that I will get PID of test.py
Related
I have issue while running subprocess in Python CGI script.
I am going to run python file as subprocess in python CGI script.
script.py
#!enable debugging
import cgitb
cgitb.enable()
print("Content-Type: text/html;charset=utf-8")
print()
import subprocess
p = subprocess.Popen(["sudo", "/usr/bin/python3", "test.py"], stdout=subprocess.PIPE)
test.py
f.open("test.txt", "a")
f.write("This is test")
f.close()
If I run script.py in console, it creates test.txt file successfully.
But If I run it on browser with Python CGI, it cannot create test.txt.
I thought, it can be caused by permission, so I tried to create test.txt in script.py directly, not on 'test.py', it is created successfully.
So, main issue is Python CGI script cannot run subprocess.
I cannot get any error while running on browser as Python CGI script.
How can I fix this issue?
Please if sudo does not work, look in the system log. There can be messages that help you with the debugging. The files are in /var/log and if you list by time ls -t you will see which ones changed just now.
First try without sudo. Make your file in a place where it does not need sudo permission like /tmp/test.txt. Then you know if the problem is sudo or something else.
I am using a python script in order to run four different python scripts that each execute a command, the purpose of this is to run the main python script on startup. This is what is inside the main python script:
#!/usr/bin/env/python
import os
os.system('x-terminal-emulator -e python ./one.py')
os.system('x-terminal-emulator -e python ./two.py')
os.system('x-terminal-emulator -e python ./three.py')
os.system('x-terminal-emulator -e python ./four.py')
When I run it, it does create four terminals and executes each of the .py in each terminal, but the one.py, two.py, and three.py return an error of "sh: 1: source: not found". I know this is because I am using these lines:
os.system('cd /home/nvidia/catkin_ws')
os.system('source devel/setup.bash')
Sourcing is needed in order the commands after it, how do I fix this problem? I am using ROS Kinetic with Linux Ubuntu 16.04.
Content of one.py
#!/bin/bash
import os
os.system('cd /home/nvidia/catkin_ws')
os.system('source devel/setup.bash')
os.system('roslaunch pocketsphinx continuous.launch spdict:=/home/nvidia/catkin_ws/src/pocketsphinx/demo/speaker_test.dic spkws:=/home/nvidia/catkin_ws/src/pocketsphinx/demo/speaker_test.kwlist sphmm:=/home/nvidia/catkin_ws/src/pocketsphinx/demo/speaker_verification/an4.ci_cont_adapt/ dict:=/home/nvidia/catkin_ws/src/pocketsphinx/demo/keywords_spk_verification.dic kws:=/home/nvidia/catkin_ws/src/pocketsphinx/demo/keywords_spk_verification.kwlist gram:=/home/nvidia/catkin_ws/src/pocketsphinx/demo/asr_spk grammar:=asr rule:=rule sp_verif:=false')
Content of two.py
#!/bin/bash
import os
os.system('cd /home/nvidia/catkin_ws')
os.system('source devel/setup.bash')
os.system('rosrun pocketsphinx execute_commands.py')
Content of three.py
#!/bin/bash
import os
os.system('cd ~/catkin_astra')
os.system('source devel/setup.bash')
os.system('roslaunch astra_launch astra.launch')
os.system() starts a new shell, executes whatever you pass it and then closes the shell down again. Subsequently created shells are not affected by any changes to that shell, like changing the working directory or sourcing stuff.
In my main Python script, I want to call another python script to run, as follows:
python2 ~/script_location/my_side_script.py \ --input-dir folder1/in_folder \ --output-dir folder1/out_folder/ \ --image-ext jpg \
From inside my Python script, how exactly can I do this?
I will be using both Windows and Ubuntu, but primarily the latter. Ideally would like to be able to do on both.
You could import the script in your main file.
Suppose you have two files: myscript.py and main.py
# myscript.py
print('this is my script!')
# main.py
print('this is my main file')
import myscript
print('end')
The output if you run main.py would be:
this is my main file
this is my script
end
EDIT: If you literally just want to call python2 my_side_script.py --options asdf, you could use the subprocess python module:
import subprocess
stdout = subprocess.check_output(['python2', 'my_side_script.py', '--options', 'asdf'])
print(stdout) # will print any output from your sidescript
I am using python 3.6.3 and subprocess module to run another python script
# main.py
#!/bin/env python
from subprocess import Popen,PIPE
from sys import executable
p = Popen([executable, 'test.py', 'arg1'],shell=True, stdout=PIPE)
p.wait()
print(p.stdout.read().decode())
and
# test.py
import sys
print(sys.argv)
I expect it will run and execute test.py. However, it opens an python interpreter in interactive mode!
I tested shell=False option, it works. I tested string form rather than list form of args, it works.
I am not sure if it is a bug or not.
You need to remove shell=True or change the first argument to be executable + ' test.py arg1' instead of [executable, 'test.py', 'arg1'].
As explained in the documentation, with shell = True, it will run it as /bin/sh -c python test.py arg1, which means python will be run without arguments.
Not sure if this is possible. I have a set of python scripts and have modified the linux PATH in ~/.bashrc so that whenever I open a terminal, the python scripts are available to run as a command.
export PATH=$PATH:/home/user/pythonlib/
my_command.py resides in the above path.
I can run my_command.py (args) from anywhere in terminal and it will run the python scripts.
I'd like to control this functionality from a different python script as this will be the quickest solution to automating my processing routines. So I need it to open a terminal and run my_command.py (args) from within the python script I'm working on.
I have tried subprocess:
import subprocess
test = subprocess.Popen(["my_command.py"], stdout=subprocess.PIPE)
output = test.communicate()[0]
While my_command.py is typically available in any terminal I launch, here I have no access to it, returns file not found.
I can start a new terminal using os then type in my_command.py, and it works
os.system("x-terminal-emulator -e /bin/bash")
So, is there a way to get the second method to accept a script you want to run from python with args?
Ubuntu 16
Thanks :)
Popen does not load the system PATH for the session you create in a python script. You have to modify the PATH in the session to include the directory to your project like so:
someterminalcommand = "my_command.py (args)"
my_env = os.environ.copy()
my_env["PATH"] = "/home/usr/mypythonlib/:" + my_env["PATH"]
combine = subprocess.Popen(shlex.split(someterminalcommand), env=my_env)
combine.wait()
This allows me to run my "my_command.py" file from a different python session just like I had a terminal window open.
If you're using Gnome, the gnome-terminal command is rather useful in this situation.
As an example of very basic usage, the following code will spawn a terminal, and run a Python REPL in it:
import subprocess
subprocess.Popen(["gnome-terminal", "-e", "python"])
Now, if you want to run a specific script, you will need to concatenate its path with python, for the last element of that list it the line that will be executed in the new terminal.
For instance:
subprocess.Popen(["gnome-terminal", "-e", "python my_script.py"])
If your script is executable, you can omit python:
subprocess.Popen(["gnome-terminal", "-e", "my_script.py"])
If you want to pass parameters to your script, simply add them to the python command:
subprocess.Popen(["gnome-terminal", "-e", "python my_script.py var1 var2"])
Note that if you want to run your script with a particular version of Python, you should specify it, by explicitly calling "python2" or "python3".
A small example:
# my_script.py
import sys
print(sys.argv)
input()
# main.py
import subprocess
subprocess.Popen(["gnome-terminal", "-e", "python3 my_script.py hello world"])
Running python3 main.py will spawn a new terminal, with ['my_script.py', 'hello', 'world'] printed, and waited for an input.