I've got a little python app that I used pyInstaller on to create an exe file:
import subprocess
try:
taskCommand = 'tasklist /FI "ImageName eq pc-client.exe"'
reply = subprocess.Popen(taskCommand, stdout = subprocess.PIPE).communicate()[0]
for line in reply.split("\n"):
if line.startswith("pc-client.exe"):
PID = line.split()[1]
print PID
except:
pass
try:
killCommand = ("TASKKILL /f /t /PID " + PID)
subprocess.Popen(killCommand, stdout = subprocess.PIPE).communicate()[0]
except:
pass
try:
print "Restarting Papercut Client..."
subprocess.Popen(r"\\server\path\to\file\filename.exe", stdout = subprocess.PIPE).communicate()[0]
except:
pass
sys.exit()
When the exe is run, it opens up in the windows command window, will run its code (it's non-interactive) and then I want the window to dissappear when its finished!
What should I put at the end of my python code to make the window close when completed. I've tried os.quit(), os._exit(), sys.quit() & sys.exit() but none of them actually close the window!
As I'm creating an exe from my code, should I use something else? I can't compile with the noconsole flag, as it needs it to actually run the commands...
Thanks.
You can block the windows command prompt from coming up at all by putting
console=False
in your spec file. For example:
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='YourApp',
console=False,
icon='IMGFolder\game_icon_cs6_icon.ico')
If you are running from the command line without a spec file, use the noconsole flag:
pyinstaller.py --noconsole yourscript.py
for more info on the PyInstaller options: https://pyinstaller.readthedocs.io/en/stable/usage.html#options
If you want the prompt to come up then close, sys.exit() works for me, but without seeing more code it will be hard to tell.
UPDATE
Since subprocesses are involved, keep in mind that the command prompt will remain open until all processes are resolved (parent and child).
It looks like you are killing the first task with its PID (I would print out the PID before you kill it to confirm you have the right one). Then you run the second task (the main file you want run?) but never kill it.
Are you trying to close the command prompt but keep the .exe running?
There is some good information about killing processes here:
How to kill a python child process created with subprocess.check_output() when the parent dies?
Related
I have a script where I launch a shell command. The problem is that the script doesn't wait until the command is finished and continues right away.
I have tried WAIT but it doesn't work as the shell command turns the source off and on (ignition off/on) and I get the error that WAIT cannot be executed because power is off.
Is there any command I can use for program to wait until the command is executed?
My script looks like this:
OS.COMMAND echo OUTP OFF > COM1
OS.COMMAND echo OUTP ON > COM1
System.up
If I would want to execute a shell command without redirecting I would use OS.Area instead of OS.Command, because OS.Area is blocking and will wait until the shell command has finished. However OS.Area does not support redirecting I think.
If I would want to execute a shell command and redirect the output to a file I would first delete the file and then wait until it gets accessible. Like this:
IF OS.FILE.EXIST("myfile.txt")
RM "myfile.txt"
OS.Command ECHO "Hello World" > "myfile.txt"
WAIT OS.FILE.readable("myfile.txt")
However it looks like you want to write via a shell command to a COM port on Windows. But I don't think it is possible to wait in TRACE32 until this write to the COM port has been done when using OS.Command...
So I suggest to do this task with the TERM commands instead:
TERM.METHOD #1 COM COM1 115200. 8 NONE 1STOP NONE
TERM.view #1
TERM.Out #1 "OUTP OFF" 0x0A
TERM.Out #1 "OUTP ON" 0x0A
Of course you have to set the correct baud rate, bits, parity and stop bits. The 0x0A after each TERM.Out is simply the line-feed character.
Does you terminal show any output as a reaction to OUTP ON? If yes you can also wait for this output with e.g. SCREEN.WAIT TERM.LINE(#1,-1)=="OUTP is now ON" 5.s
Otherwise I assume that a simple WAIT 50.ms before SYStem.Up will probably do the trick too.
I am trying to understand this line of Code:
def delete_dir(dir):
with open('/dev/null', 'w+') as null:
subprocess.Popen("rm -r %s" % dir, shell=True, stdout=null, stderr=null).wait()
I'm new to programming so I lack the context to understand why this process is set to wait. What are some common practice implementation to setting a process to wait. Thanks
Popen.wait doesn't tell the process to wait, it tells our script to wait for the process to terminate before continuing execution. This is useful whenever the child process is doing something that will affect the behaviour of our script.
In this case, we are waiting for the rm -r command to finish deleting the given directory before we continue, because if our function is called delete_dir it is reasonable for the caller to expect the directory to be deleted before the function returns.
The purpose of with open('/dev/null', 'w+') as null (if you are curious) is to suppress any output of the child process by piping its stdout and stderr to the /dev/null handle.
I currently have the below code:
processlist = []
for p in psutil.process_iter():
try:
process = psutil.Process(p.pid)
pname = process.name()
processlist.append(pname)
except:
pass
if "tor.exe" in processlist:
os.system("Taskkill /im tor.exe")
process = subprocess.Popen(r"C:\Program Files (x86)\Tor Browser\Browser\firefox.exe", stdout=subprocess.PIPE)
In essence,I want the Python code to kill the Tor Browser if it is open and to then reopen it. Nonetheless, when I run this code, the Tor browser displays a message stating that there is an error with the Browser and would the user like to close and restart the browser? I don't really want this to happen and so I'm just wondering if there is another way of closing the browser avoiding this confirmation prompt message?
Type taskkill /?
All you are doing is asking Tor (whatever that is) to close, ie send a WM_Close message. /f terminates an application.
I'm running several simulations using Condor and have coded the program so that it outputs a progress status in the console. This is done at the end of a loop where it simply prints the current time (this can also be percentage or elapsed time). The code looks something like this:
printf("START");
while (programNeedsToRum) {
// Run code repetitive code...
// Print program status update
printf("[%i:%i:%i]\r\n", hours, minutes, seconds);
}
printf("FINISH");
When executing normally (i.e. in the terminal/cmd/bash) this works fine, but the condor nodes don't seem to printf() the status. Only once the simulation has finished, all the status updates have been outputted to the file but then it's no longer of use. My *.sub file that I submit to condor looks like this:
universe = vanilla
executable = program
output = out/out-$(Process)
error = out/err-$(Process)
queue 100
When submitted the program executes (this is confirmed in condor_q) and the output files contain this:
START
Only once the program has finished running its corresponding output file shows (example):
START
[0:3:4]
[0:8:13]
[0:12:57]
[0:18:44]
FINISH
Whilst the program executes, the output file only contains the START text. So I came to the conclusion that the file is not updated if the node executing program is busy. So my question is, is there a way of updating the output files manually or gather any information on the program's progress in a better way?
Thanks already
Max
What you want to do is use the streaming output options. See the stream_error and stream_output options you can pass to condor_submit as outlined here: http://research.cs.wisc.edu/htcondor/manual/current/condor_submit.html
By default, HTCondor stores stdout and stderr locally on the execute node and transfers them back to the submit node on job completion. Setting stream_output to TRUE will ask HTCondor to instead stream the output as it occurs back to the submit node. You can then inspect it as it happens.
Here's something I used a few years ago to solve this problem. It uses condor_chirp which is used to transfer files from the execute host to the submitter. I have a python script that executes the program I really want to run, and redirects its output to a file. Then, periodically, I send the output file back to the submit host.
Here's the Python wrapper, stream.py:
#!/usr/bin/python
import os,sys,time
os.environ['PATH'] += ':/bin:/usr/bin:/cygdrive/c/condor/bin'
# make sure the file exists
open(sys.argv[1], 'w').close()
pid = os.fork()
if pid == 0:
os.system('%s >%s' % (' '.join (sys.argv[2:]), sys.argv[1]))
else:
while True:
time.sleep(10)
os.system('condor_chirp put %s %s' % (sys.argv[1], sys.argv[1]))
try:
os.wait4(pid, os.WNOHANG)
except OSError:
break
And my submit script. The problem ran sh hello.sh, and redirected the output to myout.txt:
universe = vanilla
executable = C:\cygwin\bin\python.exe
requirements = Arch=="INTEL" && OpSys=="WINNT60" && HAS_CYGWIN==TRUE
should_transfer_files = YES
transfer_input_files = stream.py,hello.sh
arguments = stream.py myout.txt sh hello.sh
transfer_executable = false
It does send the output in its entirety, so take that in to account if you have a lot of jobs running at once. Currently, its sending the output every 10 seconds .. you may want to adjust that.
with condor_tail you can view the output of a running process.
to see stdout just add the job-ID (and -f if you want to follow the output and see the updates immediately. Example:
condor_tail 314.0 -f
I've got a GUI C++ program that takes a shell command from the user, calls forkpty() and execvp() to execute that command in a child process, while the parent (GUI) process reads the child process's stdout/stderr output and displays it in the GUI.
This all works nicely (under Linux and MacOS/X). For example, if the user enters "ls -l /foo", the GUI will display the contents of the /foo folder.
However, bash niceties like output redirection aren't handled. For example, if the user enters "echo bar > /foo/bar.txt", the child process will output the text "bar > /foo/bar.txt", instead of writing the text "bar" to the file "/foo/bar.txt".
Presumably this is because execvp() is running the executable command "echo" directly, instead of running /bin/bash and handing it the user's command to massage/preprocess.
My question is, what is the correct child process invocation to use, in order to make the system behave exactly as if the user had typed in his string at the bash prompt? I tried wrapping the user's command with a /bin/bash invocation, like this: /bin/bash -c the_string_the_user_entered, but that didn't seem to work. Any hints?
ps Just calling system() isn't a good option, since it would cause my GUI to block until the child process exits, and some child processes may not exit for a long time (if ever!)
If you want the shell to do the I/O redirection, you need to invoke the shell so it does the I/O redirection.
char *args[4];
args[0] = "bash";
args[1] = "-c";
args[2] = ...string containing command line with I/O redirection...;
args[4] = 0;
execv("/bin/bash", args);
Note the change from execvp() to execv(); you know where the shell is - at least, I gave it an absolute path - so the path-search is not relevant any more.