This question already has answers here:
How do I execute a program or call a system command?
(65 answers)
Closed 6 years ago.
Very new to Python.
I have a Python script with a menu. At one selection, I want to start or call another script but it's BASH. The result is put in a text file in /tmp.
I want to do this:
Start Python script. At menu selection, have it start the BASH script. At end return back to Python script which processes the file in /tmp.
Is this possible? How would I do it?
You're looking for the subprocess module, which is part the standard library.
The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes.
In Unix systems, this means subprocess can spawn new Unix processes, execute their results, and fetch you back their output. Since a bash script is executed as a Unix process, you can quite simply tell the system to run the bash script directly.
A simple example:
import subprocess
ls_output = subprocess.check_output(['ls']) # returns result of `ls`
You can easily run a bash script by stringing arguments together. Here is a nice example of how to use subprocess.
All tasks in subprocess make use of subprocess.Popen() command, so it's worth understanding how that works. The Python docs offer this example of calling a bash script:
>>> import shlex, subprocess
>>> command_line = raw_input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print args
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # Success!
Note the only important part is passing a list of arguments to Popen().
Related
This question already has answers here:
subprocess.Popen() error (No such file or directory) when calling command with arguments as a string
(2 answers)
Closed 2 years ago.
I am trying to write a program that opens a gnome-terminal window and executes a python file in it.
When I call the gnome-terminal subprocess with the subprocess module like this:
import subprocess
subprocess.call(['gnome-terminal', '-x', 'python3 '+filename])
I get the following error:
Failed to execute child process "python3 /home/user/Documents/test.py” (No such file or directory)
I have tried to cd to the directory /home/user/Documents/test.py first and then run the file, but it didn't work.
You're trying to execute the literal command python3 /home/user/Documents/test.py which obviously doesn't exist on your system.
When you type that line in a shell, the shell will split it on spaces and in the end it will call python3 with /home/user/Documents/test.py as argument.
When using subprocess.call, you have to do the splitting yourself.
I believe you need to pass your filename as another element in the array. I don't have gnome-terminal, but I replicated your issue with plain sh.
import subprocess
subprocess.call(['gnome-terminal', '-x', 'python3', filename])
Try this:
from os import system
system("gnome-terminal -e 'bash -c \"python3 %s\"'"%filename)
Add other commands using a semicolon:
system("gnome-terminal -e 'bash -c \"python3 %s; [second command]\"'")
Try this (i assume that python3 is set in PATH)
from subprocess import Popen
command="gnome-terminal -x python3"+filename
proc=Popen(command)
if this not works
then try to run your python file first , and see if it works or not
python filename
I would like to know how I can use command prompt in python. Here is the thing, I need to run a program which is python based,and I used to do it in command prompt. However, I need to run this program multiple times and, thus, would like to automate it. The program need to run with files in a specific folder, and it uses a config file located in the same specific folder. Finally, I also need it to give a log file once it finishes each process. I used to do all this in command prompt:
C:\Users\Gabriel\Documents\vina_tutorial>"\Program Files (x86)\The Scripps Research Institute\Vina\vina.exe" --config conf.txt --log log.txt
I tried using python:
import subprocess
subprocess.Popen('C:\\Program Files (x86)\\The Scripps Research Institute\\Vina\\vina.exe -config ' + 'conf.txt', cwd='C:\\Users\\Gabriel\\Documents\\vina_tutorial')
However, it didn't seem to work. (I did omit the log file thing in this first step)
Any tips on how to proceed or where I can learn something about it?
You need to split up your shell command into separate arguments passed into Popen. Read the documentation
>>> import shlex, subprocess
>>> command_line = input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print(args)
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # Success!
Also, you may need to escape the backslashes in the Windows filepath. You may also need to enclose quotes IE '"C:\\Program Files (x86)\\etc..\\foo.exe"'
Typing the command in my ubuntu terminal recognizes the parameter t in my command:
/home/daniel/Downloads/SALOME-7.6.0-UB14.04/salome start -t
What is the difference when starting the same process in python via Popen?
command ='/home/daniel/Downloads/SALOME-7.6.0-UB14.04/salome'
commandargs= 'start -t'
import subprocess
subprocess.Popen([command, commandargs], shell=True).wait()
My parameter stands for terminal mode but running my application (salome) via python Popen opens the GUI.
See: https://docs.python.org/3.5/library/subprocess.html#subprocess.Popen
args should be a sequence of program arguments or else a single string.
See also: https://stackoverflow.com/a/11309864/2776376
subprocess.Popen([command, commandargs.split(' ')], shell=True).wait()
alternatively you could do, although less recommended:
subprocess.Popen(command + commandargs, shell=True).wait()
should do the trick
The python script I would use (source code here) would parse some arguments when called from the command line. However, I have no access to the Windows command prompt (cmd.exe) in my environment. Can I call the same script from within a Python console? I would rather not rewrite the script itself.
%run is a magic in IPython that runs a named file inside IPython as a program almost exactly like running that file from the shell. Quoting from %run? referring to %run file args:
This is similar to running at a system prompt python file args,
but with the advantage of giving you IPython's tracebacks, and of
loading all variables into your interactive namespace for further use
(unless -p is used, see below). (end quote)
The only downside is that the file to be run must be in the current working directory or somewhere along the PYTHONPATH. %run won't search $PATH.
%run takes several options which you can learn about from %run?. For instance: -p to run under the profiler.
If you can make system calls, you can use:
import os
os.system("importer.py arguments_go_here")
You want to spawn a new subprocess.
There's a module for that: subprocess
Examples:
Basic:
import sys
from subprocess import Popen
p = Popen(sys.executable, "C:\test.py")
Getting the subprocess's output:
import sys
from subprocess import Popen, PIPE
p = Popen(sys.executable, "C:\test.py", stdout=PIPE)
stdout = p.stdout
print stdout.read()
See the subprocess API Documentation for more details.
Using Python , I would like to start a process in a new terminal window, because so as to show the user what is happening and since there are more than one processes involved.
I tried doing:
>>> import subprocess
>>> subprocess.Popen(['gnome-terminal'])
<subprocess.Popen object at 0xb76a49ac>
and this works as I want, a new window is opened.
But how do I pass arguments to this? Like, when the terminal starts, I want it to say, run ls. But this:
>>> subprocess.Popen(['gnome-terminal', 'ls'])
<subprocess.Popen object at 0xb76a706c>
This again works, but the ls command doesn't: a blank terminal window starts.
So my question is, how do I start the terminal window with a command specified, so that the command runs when the window opens.
PS: I am targetting only Linux.
$ gnome-terminal --help-all
...
-e, --command Execute the argument to this option inside the terminal
...
If you want the window to stay open then you'll need to run a shell or command that keeps it open afterwards.
In [5]: import subprocess
In [6]: import shlex
In [7]: subprocess.Popen(shlex.split('gnome-terminal -x bash -c "ls; read -n1"'))
Out[7]: <subprocess.Popen object at 0x9480a2c>
this is the system that I use to launch a gnome-terminal from notepad++ in WINE,
1:notepad++ command to launch
#!/usr/bin/python
#this program takes three inputs:::
#$1 is the directory to change to (in case we have path sensitive programs)
#$2 is the linux program to run
#$3+ is the command line arguments to pass the program
#
#after changing directory, it launches a gnome terminal for the new spawned linux program
#so that your windows program does not eat all the stdin and stdout (grr notepad++)
import sys
import os
import subprocess as sp
dir = sys.argv[1]
dir = sp.Popen(['winepath','-u',dir], stdin=sp.PIPE, stdout=sp.PIPE).stdout.read()[:-1]
os.chdir(os.path.normpath(os.path.realpath(dir)))
print os.getcwd()
print "running '%s'"%sys.argv[2]
cmd=['gnome-terminal','-x','run_linux_program_sub']
for arg in sys.argv[2:]:
cmd.append(os.path.normpath(os.path.realpath(sp.Popen(['winepath','-u',arg], stdin=sp.PIPE, stdout=sp.PIPE).stdout.read()[:-1])))
print cmd
p = sp.Popen(cmd, stdin=sp.PIPE, stdout=sp.PIPE)
2: run sub script, which I use to run bash after my program quits (python in this case normally)
#!/bin/sh
#$1 is program to run, $2 is argument to pass
#afterwards, run bash giving me time to read terminal, or do other things
$1 "$2"
echo "-----------------------------------------------"
bash