I am familiar with how to open a terminal from Python (os.system("gnome-terminal -e 'bash -c \"exec bash\"'")), but is there a way to open another terminal running the same program that opened the new terminal?
For instance, if I was running a program called foo.py and it opened another terminal, the new terminal would also be running foo.py.
See this question, it's pretty close. You want to add sys.argv as a parameter, though:
import sys
import subprocess
cmd = 'xterm -hold -e ./{0}'.format(' '.join(sys.argv))
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Be sure you somehow check how many processes/terminals you run already, otherwise it will hang your machine in a matter of seconds.
Related
Using python I can get either of these to work:
subprocess.call(['wine', 'cmd'])
os.system("wine cmd")
I'm using Ubuntu and python 3.5, Once I get into the wine cmd prompt I can no longer run commands, non of the ways to run multiple commands that I have seen online work, they don't error out, it just opens the cmd and pauses, I think it treats the cmd once open as a running command and is waiting to move on to the next command which it assumes is for the shell not the wine cmd, how can i then run commands inside the wine cmd once opened?
edit: Basically any time I run a command that requires further user input from within that command, how do I interact inside of that command?
You could build up from DOS through BASH to python as in the example code here. I cut and paste the code into python 2.7 and it worked, but you might like to confirm on 3.5
If you specifically need interaction rather than just running a DOS command then you could use subprocess.Popen.communicate to interact with your script which then interacts with wine/dos.
import subprocess, os, stat
from subprocess import Popen
from subprocess import PIPE
from subprocess import check_output
command_script="/tmp/temp_script.sh"
f1 = open(command_script,'w')
f1.write("#!/bin/bash\n")
#to run a dos command
#f1.write(r'WINEPREFIX=/path/tp/wine/prefix wine cmd /c #mydoscommand argval1'+'\n')
#for example
f1.write(r'wine cmd /c #echo Hello_world'+'\n')
#or to run a specifically pathed executable
#f1.write(r'WINEPREFIX=/path/tp/wine/prefix wine "c:\\Program Files (x86)\\path\\to\\executable.exe" additionalargs '+'\n')
f1.close()
st = os.stat(command_script)
os.chmod(command_script, st.st_mode | stat.S_IEXEC)
p = Popen(command_script, stdin=PIPE, stdout=PIPE, stderr=PIPE)
output, err = p.communicate(b"input data that is passed to subprocess' stdin")
rc = p.returncode
print output
os.remove(command_script)
Have a look at the answers where I nicked some of the code from Running windows shell commands with python and calling-an-external-command-in-python
I need to run a bash script from Python. I got it to work as follows:
import os
os.system("xterm -hold -e scipt.sh")
That isn't exactly what I am doing but pretty much the idea. That works fine, a new terminal window opens and I hold it for debugging purposes, but my problem is I need the python script to keep running even if that isn't finished. Any way I can do this?
I recommend you use subprocess module: docs
And you can
import subprocess
cmd = "xterm -hold -e scipt.sh"
# no block, it start a sub process.
p = subprocess.Popen(cmd , shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# and you can block util the cmd execute finish
p.wait()
# or stdout, stderr = p.communicate()
For more info, read the docs,:).
edited misspellings
I have a bit of code that I am designing to take a file, perform the dos2unix command on it, then copy that file to a file called INPUT, and then run a command that boots a program. From my code the first two tasks work flawlessly, however the script doesn't seem to excecute the command line which starts the program. However when I take the command line exactly as I have it written in the script, and pass it in terminal, it works fine.
here is the code:
import subprocess
import os
os.chdir('/home/mike/testing/crystal')
subprocess.Popen(['dos2unix mgo_input'], stdout=subprocess.PIPE, shell=True)
subprocess.call(['cp mgo_input INPUT'], shell=True)
subprocess.Popen(['mpirun -np 8 Pcrystal </dev/null &> mgo_singlepoint.out &'], stdout=subprocess.PIPE, shell=True)
it is the mpirun section of the code that seems to be getting hung up
Popen() returns before the called program finishes execution. Using call (or check_call, which checks return codes) can be a better solution. Better yet, use python for the conversion and the copy.
I'm not sure why you are piping stdout, but I'm going to assume you don't want dos2unix or mpirun to print to the screen, so I redirect them to /dev/null.
import subprocess
import shutil
import os
os.chdir('/home/mike/testing/crystal')
subprocess.check_call('dos2unix mgo_input', stdout=open('/dev/null','w'), shell=True)
shutil.copy2(mgo_input, 'INPUT')
subprocess.check_call('mpirun -np 8 Pcrystal', stdout=open('mgo_singlepoint.out', 'w'), stdstderr=subprocess.STDOUT, shell=True)
So I am running a command in my python py file
myNewShell = os.system('start "%s" /d "%s" cmd /f:on /t:0A /k "W:\\Desktop\\alias.bat"' % (myShot, myWorkDir))
This opens up a shell
How exactly would I input something into this shell directly from my python script, thus bypassing your actual cmd.exe. I have a bunch of DOSKEYs set up, such as maya which opens up the maya program. How would I add a line of code to my python script, so that it loads the shell with those aliases and inputs my command directly
Take a look at the powerful and useful subprocess module
You can then do code like this
import subprocess
pro = subprocess.Popen("cmd", stdout=subprocess.PIPE, stdin=subprocess.PIPE)
pro.stdin.write("mybat.bat\n")
pro.stdin.write("myother.bat\n")
pro.stdin.write("start mysillyprogram\n")
pro.stdin.flush()
pro.terminate() # kill the parent
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