I'm working in a windows environment (my laptop!) and I need a couple of scripts that run other programs, pretty much like a windows batch file.
how can I run a command from python such that the program when run, will replace the script? The program is interactive (for instance, unison) and keeps printing lines and asking for user input all the time.
So, just running a program and printing the output won't suffice. The program has to takeover the script's input/output, pretty mcuh like running the command from a .bat file.
I tried os.execl but it keeps telling me "invalid arguments", also, it doesn't find the program name (doesn't search the PATH variable); I have to give it the full path ..?!
basically, in a batch script I can write:
unison profile
how can I achieve the same effect in python?
EDIT:
I found out it can be done with os.system( ... ) and since I cannot accept my own answer, I'm closing the question.
EDIT: this was supposed to be a comment, but when I posted it I didn't have much points.
Thanks Claudiu, that's pretty much what I want, except for a little thing: I want the function to end when the program exits, but when I try it on unison, it doesn't return control to the python script, but to the windows command line environment
>>> os.execlp("unison")
C:\>Usage: unison [options]
or unison root1 root2 [options]
or unison profilename [options]
For a list of options, type "unison -help".
For a tutorial on basic usage, type "unison -doc tutorial".
For other documentation, type "unison -doc topics".
C:\>
C:\>
C:\>
how to get around this?
You should create a new processess using the subprocess module.
I'm not fluent in windows processes but its Popen function is cross-platform, and should be preffered to OS specific solutions.
EDIT: I maintain that you should prefer the Subprocess module to os.* OS specific functions, it is cross-platform and more pythonic (just google it). You can wait for the result easily, and cleanly:
import os
import subprocess
unison = os.path.join(os.path.curdir, "unison")
p = subprocess.Popen(unison)
p.wait()
I found out that os.system does what I want,
Thanks for all that tried to help.
os.system("dir")
runs the command just as if it was run from a batch file
import subprocess
proc = subprocess.Popen(['unison', 'profile'], stderr=subprocess.PIPE,
stdout=subprocess.PIPE, stdin=subprocess.PIPE)
proc.stdin.write('user input')
print proc.stdout.read()
This should help you get started. Please edit your question with more information if you want a more detailed answer!
os.execlp should work. This will search your path for the command. Don't give it any args if they're not necessary:
>>> import os
>>> os.execlp("cmd")
D:\Documents and Settings\Claudiu>Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
D:\Documents and Settings\Claudiu>
Related
Hello I am having this problem where i want to automatically check the system32 file folder with the sfc cmd commands like sfc /verifyonly but the problem is that I can execute only one line in the cmd but I need to execute two and don't know how to execute a second one
import os
os.system("start /B start cmd.exe #cmd /k sfc")
I need another command for sfc /verifyonly so the program would work fully automatic can somebody help with anything pls
I tried a lot of things but nothing seemed to work for me or i am just really stupid and can't find the exact command i should be using
If you look at the docs for os.system they mention the subprocess module as being a more recent development within python that supports multiple systems level processes
I have been having some problems with subprocess.call(), subprocess.run(), subprocess.Popen(), os.system(), (and other functions to run command prompt commands) as I can't seem to get the msg command to work.
import subprocess
subprocess.call("msg * Hey",shell=True)
In theory, this should send "Hey" to every computer on the network unfortunately, this isn't running at all and I'm not quite sure why. I can run it on cmd successfully, but can't get it to work from Python.
I'd love to hear why this doesn't work and hopeful a way to fix my code or an alternate solution.
Edit: Solved, thanks for everyone's help. Upgrading to 64-bit Python did the trick.
In 64-bit Windows, "msg.exe" is only distributed as a native 64-bit binary. This file won't be found if you're using 32-bit Python, which executes under WOW64 emulation. WOW64 redirects "System32" access to the "SysWOW64" directory. In Windows 7+, use the virtual "SysNative" directory to access the real "System32". For example:
sysroot = os.environ['SystemRoot']
sysnative = os.path.join(sysroot, 'SysNative')
if not os.path.exists(sysnative):
sysnative = os.path.join(sysroot, 'System32')
msgexe_path = os.path.join(sysnative, 'msg.exe')
subprocess.call([msgexe_path, '*', 'Hey'])
Note that msg.exe has nothing to do with CMD, so there's no reason to use shell=True.
Try calling it as separate arguments:
subprocess.call(['msg', '*', 'Hey'], shell=True)
Try putting the complete path of the msg command. Example as listed
import subprocess
subprocess.call("/usr/local/bin/msg * Hey",shell=True)
What I want is to have a desktop shortcut that will run a script. I've been trying to use batch and Python, but I don't really care what language if it works. I need the script to open a bash shell (Windows Subsystem for Linux) and execute simple commands while keeping the shell open. At first, I thought this would simple, but now I'm questioning if it's even possible. I made a simple batch file that would get as far as opening bash and keep it open, but the test command I put in didn't make it to the shell. (I didn't really expect it to but I can't think of a good way to do this, so I've just been trying random stuff). Here is the batch file I used:
bash
cowsay test
PAUSE
After this, I tried using a Python script to open bash and run a shell script that would keep the shell open and execute commands. Here is the Python script:
import os
import time
os.system("start /wait bash /c {./test.sh}")
while 1:
time.sleep(2)
For some reason, this gives an error saying it can't find bash. This isn't really for a project or anything. It's actually for a friend's computer as kind of a joke, but I would really like to know if this is possible. If anyone has any ideas how this could work, I would appreciate it because I'm out of ideas and can't find any other similar questions.
Yes, you can do something like this
import subprocess
from subprocess import Popen
p = Popen("batch.bat", cwd=r"C:\Path\to\batchfolder")
stdout, stderr = p.communicate()
So as the title says, I'm having problem starting a new subprocess under Fedora. Now the situation is, I have a main python script from which I start a couple of other python processes using:
import subprocess
subprocess.Popen(['python', '-m', 'first_child.run', 'start'], shell=False)
Now this works fine on MacOS, debian and windows. On fedora if I run it from Aptana 3 IDE it also works, the only problem is when i try to run this main scrip from a terminal, where I get:
OSError: [Errno 2] No such file or directory
Do you have any ideea what can be the problem here?
Regards,
Bogdan
Sorry if this is something you've already thought of -- but the most common cause of OSError from calls to subprocess is that it cannot find the process
http://docs.python.org/library/subprocess.html#exceptions
Are you absolutely certain python is in your path?
I know you're probably going to point out you ran this script from the python executable -- but I thought I'd take a shot that perhaps you specified the full path to python when you ran it from the terminal.
For fun, right before the call to subprocess, you could dump your PATH
import os
print os.environ['PATH']
It's your current working directory. I don't think the problem is that it can't find python, the problem is that it can't find first_child.run.
Try printing os.getcwd() before you launch the subprocess, and see if it's different in the terminal vs. in the IDE.
On a side note, it's probably more reliable to use sys.executable as the python you use in your subprocess, as opposed to just saying python. For example, subprocess.Popen([sys.executable, '-m', 'first_child.run', 'start'], shell=False)
When I launch a PowerShell script from Python, the delay seems to be approximately 45s, and I cannot figure out why.
I'm trying to run a PowerShell script (accessing some APIs only available to PowerShell) from a Python script.
I've tried a lot of permutations, and all incur ~45 second delay compared to just running the script from a command prompt, using an identical command line.
For example - sample.ps1 might say:
echo foo
And runner.py might say:
import subprocess
p = subprocess.Popen([POWERSHELL, '-File', 'sample.ps1'], stdout=subprocess.STDOUT)
d = p.stdout.read()
Running the .ps1 script directly is fast, running it via runner.py (Python 2.7, 32bit on a 64bit machine) incurs 45 second delay.
The exact same thing occurs if I use "os.system", or Twisted's built-in process tools. So I suspect it's some subtle interaction between the Python interpreter and the Powershell interpreter, possibly related to creation of console windows, or handling of stdin/out/err streams? (which I know don't "really exist" in the same way on Windows)
I do not see any such delays. It is pretty snappy. ( that will also depend on what your script actually does.) Try using call:
from subprocess import call
call(["powershell", "sample.ps1"])
PowerShell loads your user's profile by default. Use the -NoProfile argument to turn that behavior off:
import subprocess
p = subprocess.Popen([POWERSHELL, '-NoProfile', '-File', 'sample.ps1'], stdout=subprocess.STDOUT)
d = p.stdout.read()