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
Related
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.
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 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.
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