Python execute command in console - python

I'm trying to make a program that takes a command and executes it in the console of any operating system and prints the response in python. For this I'm using subprocess.check_output. The program works fine with the ipconfig command (I'm on windows), and the response gets printed after no time. With the notepad command, it opens notepad and only continues when I close notepad. Is it possible to just continue without notepad being closed?
Code:
import subprocess
def executeCommand(command):
return subprocess.check_output(command).decode('ISO-8859-1')
def cmdCommand(command):
pool = ThreadPool(processes=1)
asynch_result = pool.apply_async(executeCommand, [command])
for i in range(3):
if asynch_result.get() is not None:
return asynch_result.get()
sleep(1)
pool.terminate()
return "No result gotten"
print(cmdCommand("ipconfig"))
print(cmdCommand("notepad"))

Related

Python subprocess wait keypress

I want to run a program using the subprocess module. While running the program, there are cases where it waits for a button press to continue. It is not waiting for this input to the stdin input. The input sent to stdin is ignored by the program. Only when I press a button on the console will the program continue running.
I tried it like this:
proc = Popen("festival.exe level.sok", stdin=PIPE, text=True)
proc.stdin.write('.')
proc.stdin.flush()
It this case nothing happened.
and like this:
proc = Popen...
proc.communicate('.')
In this case, the python code will not continue running until I press a button on the console. If I set a timeout then the python code continues to run but festival.exe does not continue to run.
What should I do to make festival.exe continue running?
P.S.: festival.exe is a solver for sokoban. This case occurs when the given level cannot be solved. E.g.:
########
#.. $ $#
# # #
########
assuming you have the festival program like this:
from random import getrandbits
solved = getrandbits(1)
if solved:
print("executed correctly")
else:
print('a error ocurred')
input('press a button to continue')
exit(1)
you can solve with:
from subprocess import Popen, PIPE
p = Popen(['python3','festival.py'],stdin=PIPE)
p.communicate(input=b'any\n')

Threading program in python running successfully on IDLE but not on shell, command line

I am using python 3.8 on windows 10. I am able to run threading programs succesfully on IDLE but, the same programs do not start on command line or when I double click them. The shell pops up and exits quickly even when threads are not started. I even tried to catch any runtime errors and any errors using except but I got neither on IDLE and the program was still terminating abruptly on shell.
Here is an example -
import threading
import time
try:
def func():
for i in range(10):
print(i)
time.sleep(0.1)
t1 = threading.Thread(target = func)
t1.start()
#t1.join() # i tried this also
while t1.is_alive():
time.sleep(0.1) #trying to return back, i added this when the threads were not working
input() #waiting for the user to press any key before exit
except RuntimeError:
print('runtime error')
input()
except: # any error
print('Some error')
input()
I found that I had made a file by the name 'threading.py' in the directory. This file was causing Attribute Error of python because it has the same name as the 'threading' module of python. I renamed it and my programs are working jolly good!

Check for open text file

I'm writing a Python application with opens several text files in different threads. I want each thread to make some operations on the file while it is open. When the external text editor closes the file the processing of the corresponding thread should stop. So I need to check on whether the text file is still opened or not.
class MyThread (Thread):
def __init__(self, sf):
Thread.__init__(self)
self.sf = sf # sourcefile
def run (self):
subprocess.Popen([EDITOR, self.sf])
The problem now is that subprocess opens the file in the editor and run() terminates. How can I keep the run() open until I close the file externally?
Did you try the subprocess.call method?
subprocess.call('notepad')
This waits for the command to complete before the process terminates and returns control back to the program.
This is what i wrote:
import subprocess
from threading import Thread
class MyThread(Thread):
def __init__(self, sf):
Thread.__init__(self)
self.sf = sf
def run(self):
subprocess.call('notepad ' + self.sf)
def main():
myThread = MyThread('test.txt')
myThread.start()
while myThread.isAlive():
print "Still Alive"
if __name__ == '__main__':
main()
The program keeps printing "Still Alive" till I close the notepad window.
You have two events: FileOpen and FileClose. FileOpen happens when the editor is opened. FileClose is done when the editor closes? Or when the editor closes the file? If it's just on closing the editor then it should be straightforward to find out when the subprocess closes and then kill the worker threads.
Unless an editor provides a particular API, it's going to be a really nasty hack to find out if it closed the file but the editor remains open. E.g. You may have to poll lsof and process the output.
It sounds similar to what a revision control system does when you commit a file and it opens an editor for you. Maybe you should check the hg or bzr code bases. Here is how mercurial handles it. And here is how bazaar handles it.
I changed Shekar's version to work with vim and use the list as a command in the subprocess.call command (and added imports) . It works as he describes.
from threading import Thread
import subprocess
class MyThread(Thread):
def __init__(self, sf):
Thread.__init__(self)
self.sf = sf
def run(self):
subprocess.call(['/usr/bin/vim', self.sf])
def main():
myThread = MyThread('test.txt')
myThread.start()
while myThread.isAlive():
print "Still Alive"
if __name__ == '__main__':
main()
I found the problem. I was calling the editor MacVim via command line with /usr/bin/mvim. Now I changed it to /Applications/MacVim.app/Contents/MacOS/MacVim and it works as expected. I think that is because it checks the only process which it handles directly, in the first case it was the terminal and not the editor.

Trapping and handling taskkill in Windows Python

I am using Python 2.6.6 for Windows (on Windows XP SP3) with pywin32-218.
In my Python application, I have a second thread (apart from the main thread) which spawns a subprocess to run another Windows executable.
My problem is that when the main process (python.exe) is killed (e.g. using taskkill), I want to terminate the subprocess (calc.exe) and perform some cleaning up.
I tried various methods (atexit, signal and win32api.handleConsoleCtrl), but none seem to be able to trap the taskkill signal.
My code as follows (test.py):
import sys
import os
import signal
import win32api
import atexit
import time
import threading
import subprocess
class SecondThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.secondProcess = None
def run(self):
secondCommand = ['C:\WINDOWS\system32\calc.exe']
self.secondProcess = subprocess.Popen(secondCommand)
print 'calc.exe running'
self.secondProcess.wait()
print 'calc.exe stopped'
# do cleanup here
def stop(self):
if self.secondProcess and self.secondProcess.returncode == None:
self.secondProcess.kill()
secondThread = SecondThread()
def main():
secondThread.start()
def cleanup():
print 'cleaning up'
secondThread.stop()
print 'cleaned up'
atexit.register(cleanup)
def handleSignal(signalNum, frame):
print 'handleSignal'
cleanup()
sys.exit(0)
for signalNum in (signal.SIGINT, signal.SIGILL, signal.SIGABRT, signal.SIGFPE, signal.SIGSEGV, signal.SIGTERM):
signal.signal(signalNum, handleSignal)
def handleConsoleCtrl(signalNum):
print ('handleConsoleCtrl')
cleanup()
win32api.SetConsoleCtrlHandler(handleConsoleCtrl, True)
main()
The application is launched using
python.exe test.py
The console then prints "calc.exe running", and the Calculator application runs, and using Process Explorer, I can see calc.exe as a sub-process of python.exe
Then I kill the main process using
taskkill /pid XXXX /f
(where XXXX is the PID for python.exe)
What happens after this is that the command prompt returns without further output (i.e. none of "cleaning up", "handleSignal" or "handleConsoleCtrl" gets printed), the Calculator application continues running, and from Process Explorer, python.exe is no longer running but calc.exe has re-parented itself.
Taskkill (normally) sends WM_CLOSE. If your application is console only and has no window, while you can get CTRL_CLOSE_EVENT via a handler set by SetConsoleCtrlHandler (which happens if your controlling terminal window is closed) you can't receive a bare WM_CLOSE message.
If you have to stick with taskkill (rather than using a different program to send a Ctrl-C) one solution is to set the aforementioned handler and ensure your application has its own terminal window (e.g. by usingstart.exe "" <yourprog> to invoke it). See https://stackoverflow.com/a/23197789/4513656 for details an alternatives.

Visual Studio Python Debugger closes right after run

I have a python project. I click on a .py file and hit run with out debugger and the console comes up and the program runs. if I use run with debugger the console flashes and close. there are words on it. but it closes to fast for me to read. I have Set everything in tools I think I can. I have python debugger interactive.
import sys class Test():
def init(self):
var = raw_input("Hit Enter")
t = 'test'
print t
stepB = raw_input("Hit Enter")
a = Test()
place brake pint at t = 'test'

Categories

Resources