Working with Command Prompt through Python - python

I want to make a script which opens a command prompt window and input commands into that prompt without any user interaction. I have been using the subprocess module with little success. What I have so far:
def subprocess_cmd(command):
process = Popen(command,stdout=PIPE, shell=True)
proc_stdout = process.communicate()[0].strip()
print proc_stdout
subprocess_cmd('"C:\system\cmd.exe" & C:\dir\mybat.bat & C:\dir\gdal_translate C:\dir2\mypdf.pdf C:\dir\mytif.tif')
Now it runs through without error, but nothing happens. There should be a .tif file in the dir2 folder but as I said, nothing appears. When I run through the command prompt myself, it works fine.

I think the problem is you are not calling the methods and constants from the subprocess class. This worked for me in Python 3:
import subprocess
def subprocess_cmd(command,c="C:\\Users\\Alex"):
process = subprocess.Popen(command,stdout=subprocess.PIPE,shell=True,cwd=c)
proc_stdout = process.communicate()[0].strip()
print(proc_stdout)
>>> subprocess_cmd('"cmd.exe" && "C:\\Users\\Alex\\test.bat"','C:\\Users\\Alex\\')
b'Microsoft Windows [Version 6.3.9600]\r\n(c) 2013 Microsoft Corporation. All rights reserved.\r\n\r\nC:\\Users\\Alex>\r\nC:\\Users\\Alex>mkdir thisisanewdirectory'
>>> subprocess_cmd('test.bat')
b'C:\\Users\\Alex>mkdir thisisanewdirectory'

Related

Running Command from Python. Works with os.system but not subprocces.run

I have been on this problem for quite a while now. I have this command line that I want run trough python:
Users\name.lastname\Desktop\TESTER\Latitude 5431\Latitude-5431-46KCM_Win10_1.0_A01.exe /s /e=C:Users\name.lastname\Desktop\TESTER\Latitude 5431
this should run the .exe and then extract the files to the specified folder. I tried this with os.system and it worked but when I run it with
import subprocess
x = '"' + "\\Users\\name.lastname\\Desktop\\TESTER\\Latitude 5431\\Latitude-5431-46KCM_Win10_1.0_A01.exe" + '" ' + "/s /e=C:Users\\name.lastname\\Desktop\\TESTER\\Latitude 5431"
p1 = subprocess.run(x, shell=True)
it only shows me 'tips' like these but no error message and the .exe is not executed.
Pass command line arguments directly to vendor installer.
Turn the return code to success if required
Latitude-5431-46KCM_Win10_1.0_A01.exe /factoryinstall /passthrough D:\Sample.xml C:\log\FI.log
Change from the default log location to C:\my path with spaces\log.txt
Latitude-5431-46KCM_Win10_1.0_A01.exe /l="C:\my path with spaces\log.txt"
Force update to continue, even on "soft" qualification errors
Latitude-5431-46KCM_Win10_1.0_A01.exe /s /f
Try running without shell=True as it makes things more complicated than it helps:
import subprocess
prog = r"C:\Users\name.lastname\Desktop\TESTER\Latitude 5431\Latitude-5431-46KCM_Win10_1.0_A01.exe"
args = ["/s", r"/e=C:\Users\name.lastname\Desktop\TESTER\Latitude 5431"]
subprocess.run([prog]+args)

7z command in Python 3.6 subprocess.run() on Windows

I have a python script that should run 7z.exe with the command: "x" and switch " -o" using subprocess.run(). The script is as follows:
import subprocess as sb
zipperpath = "C:\\Program Files\\7-zip\\7z.exe"
dirname ="C:\\Users\\ajain\\Desktop\\TempData"
archivename="UnprocessedData_v3.7z"
outputfilename="foo"
sb.run([zipperpath,"x",os.path.join(dirname,archivename)," -o",os.path.join(dirname,outputfilename)])
Output is:
Although the return code is 0, the zip never gets unzipped.
Try with this :
import subprocess
# variable cmd is is your command line , like you put in your console
cmd='7z.exe x UnprocessedData_v3.7z'
process = subprocess.Popen(cmd,shell=True,stdin=None,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
# The output from your shell command in an array
result=process.stdout.readlines()
if len(result) >= 1:
for line in result:
print(line)

Using Applescript to fire python script

I'm trying to use Applescript to fire a python script. When I fire it from terminal, everything works fine, but when I fire from Applescript, it appears to run but nothing happens.
I've tried all manner of combinations for everything I can find in searches and other posts for using "python file.py" or "/usr/bin/python file.py" with "#!/usr/bin/env python" and "#!/usr/bin/python".
If I enter "which python" in terminal, I get "/usr/bin/python"
Right now I have both scripts broken down to their base components. I'll eventually be using Applescript to pass a file path into python using sys.argv[1] (which is why I'm using Applescript to fire the python script) but I'm not even that far along yet as the below doesn't work yet.
Applescript
do shell script "/usr/bin/python $HOME/Desktop/test.py"
Python
#!/usr/bin/python
import sys
import os
# The notifier function
def notify(title, subtitle, message):
t = '-title {!r}'.format(title)
s = '-subtitle {!r}'.format(subtitle)
m = '-message {!r}'.format(message)
os.system('terminal-notifier {}'.format(' '.join([m, t, s])))
# Calling the function
notify(title = 'Message Test',
subtitle = 'Test1:',
message = 'Test2')
sys.exit(0)
The python script sends a notifier message. Every time I run in terminal, I receive the message without issue. Every time I run the applescript to do as shell script it runs without error-ing in AS, but no message comes from Python.
Anyone have thoughts on where I've gone wrong?
Does it work for you if you use a full path to the binary? It worked for me in both BBEdit and Smile (script editor). My path is:
/Applications/terminal-notifier-2.0.0/terminal-notifier.app/Contents/MacOS/terminal-notifier
So I used:
#!/usr/bin/python
import sys
import os
# The notifier function
def notify(title, subtitle, message):
t = '-title {!r}'.format(title)
s = '-subtitle {!r}'.format(subtitle)
m = '-message {!r}'.format(message)
os.system('/Applications/terminal-notifier-2.0.0/terminal-notifier.app/Contents/MacOS/terminal-notifier {}'.format(' '.join([m, t, s])))
# Calling the function
notify(title = 'Message Test',
subtitle = 'Test1:',
message = 'Test2')
sys.exit(0)

Execute .R script within Python using Rscript.exe shell

I have an .R file saved locally at the following path:
Rfilepath = "C:\\python\\buyback_parse_guide.r"
The command for RScript.exe is:
RScriptCmd = "C:\\Program Files\\R\\R-2.15.2\\bin\\Rscript.exe --vanilla"
I tried running:
subprocess.call([RScriptCmd,Rfilepath],shell=True)
But it returns 1 -- and the .R script did not run successfully. What am I doing wrong? I'm new to Python so this is probably a simple syntax error... I also tried these, but they all return 1:
subprocess.call('"C:\Program Files\R\R-2.15.2\bin\Rscript.exe"',shell=True)
subprocess.call('"C:\\Program Files\\R\\R-2.15.2\\bin\\Rscript.exe"',shell=True)
subprocess.call('C:\Program Files\R\R-2.15.2\bin\Rscript.exe',shell=True)
subprocess.call('C:\\Program Files\\R\\R-2.15.2\\bin\\Rscript.exe',shell=True)
Thanks!
The RScriptCmd needs to be just the executable, no command line arguments. So:
RScriptCmd = "\"C:\\Program Files\\R\\R-2.15.2\\bin\\Rscript.exe\""
Then the Rfilepath can actually be all of the arguments - and renamed:
RArguments = "--vanilla \"C:\\python\\buyback_parse_guide.r\""
It looks like you have a similar problem to mine. I had to reinstall RScript to a path which has no spaces.
See: Running Rscript via Python using os.system() or subprocess()
This is how I worked out the communication between Python and Rscript:
part in Python:
from subprocess import PIPE,Popen,call
p = subprocess.Popen([ path/to/RScript.exe, path/to/Script.R, Arg1], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
out = p.communicate()
outValue = out[0]
outValue contains the output-Value after executing the Script.R
part in the R-Script:
args <- commandArgs(TRUE)
argument1 <- as.character(args[1])
...
write(output, stdout())
output is the variable to send to Python

Python 2.5 and Tskill

I had the tskill operation working fine through a python script when using Python 2.7 but when I switched to 2.5 this code fails.
import os
import time
import win32com.client
os.startfile('cmd')
shell = win32com.client.Dispatch("WScript.Shell")
shell.AppActivate('Administrator:C:\Windows\System32\cmd.exe')
time.sleep(2)
shell.SendKeys('tskill java + {ENTER}')
time.sleep(2)
shell.Sendkeys('tskill javaw + {ENTER}')
#shell.SendKeys('exit + {ENTER}')
I use os.startfile to run a python script that opens and runs the application(It's a graphics tool).
Note: The application is already running by the time this script is called, hence I don't need to open it here.
Can some one please tell me how to close an application successfully using this or similar method on Python 2.5. Thanks for the help!
I don't have tskill on my system, but I think it's similar to taskkill /F /FI "IMAGENAME eq java*". Anyway, here's how to call a normal console application in the background (i.e. a hidden window) using the subprocess module (tested in Python 2.5.2, but using taskkill instead):
import subprocess
def tskill(*args):
si = subprocess.STARTUPINFO()
si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
command = ('tskill',) + args
rc = subprocess.call(command, startupinfo=si)
return rc == 0
if tskill('java') and tskill('javaw'):
#success
I used call because it only matters whether the call succeeds or fails, but in general you can use subprocess.PIPE to capture stdout and stderr using subprocess.Popen.
Edit: How to kill a process started with the subprocess module
command = ['path/to/executable', 'arg0', 'arg1', '...']
p = subprocess.Popen(command)
#do something
#kill if it's still alive
if p.poll() is None:
p.kill()

Categories