Python script embedded in bash, does not exit - python

I'm having a curious problem. I have a bash script that is calling a python script within it. The python script executes successfully, but never fully terminates
Content of Bash script:
#! /usr/bin/env bash
python python_script.py
echo "bar"
content of Python script:
#Much stuff
sys.exit("The python script just ended")
What I expect to see on termination would be:
>The python script just ended
>bar
What I instead get is:
>The python script just ended
If I keyboard interrupt, the bash continues as:
^C>bar
What gives? Clearly the exit is calling properly, and there is nothing between that and the output statement in the bash script that called the python script.
(I can't necessarily give specifics on the workings of the "Much stuff" in the python script, as I'm modifying existing code that I don't fully understand. I've mostly left the workings of the script alone, and modified output more than anything for formatting, but I'm happy to try and provide you with any additional information requested)

What sys.exit() does is throw an exception of type SystemExit. If your script were to catch this exception, it would continue executing past sys.exit().
Also, if you have non-daemon threads, these could be preventing the process from terminating.
If that's the case, you can either turn them into daemon threads, or somehow signal to them that you wish to exit the script, and let them shut themselves down.
Finally, there's os._exit(), but you should not have to resort to that.

The following also works:
import os
print('Hellow world')
os._exit(os.EX_OK)
In Ubuntu, it exits the terminal. See also the example in this link Program With the os.exit() Method

Related

Running bash script within python and wait for shell command to complete

I have the same question as here with python 3.x. I tried the solution provided but it does not work for me.
Python does not wait bash script to finish and prints "end" before bash script to be terminated.
I am on windows and have cygwin isntalled.
callBash.py:
import subprocess
print("start")
subprocess.call("sleep.sh",shell=True)
print("end")
sleep.sh:
#!/bin/bash
sleep 10
You never check the return value of subprocess.call, so it's likely that your script doesn't even start properly, maybe because of invalid PATH / CWD or permissions or something else.
Use subprocess.check_call instead, so that an exception is raised if your script fails to run. Exceptions are not so easy to miss.
Also if you have Python 3, subprocess.run(..., check=True) is newer and generally easier to work with.

Call bash script after exiting python program

I'm new to Python and have been able to find answers to most of my questions here so I thought you guys could help me with this one:
I'm developing somewhat of a hybrid application using bash scripts to show menus and to call python applications (I'm doing it this way to simplify things).
My problem is that when I end the python application, it simply terminates the process and to go back to the menus, I have to start the whole program again. I tried using "subprocess.call('xxx')" but it opens the bash scrips inside of the application I am running and shows text (echo) only, no other functions.
Is there a way to end the python application first and then call the shell script?
You can wrap your code in a while-true loop
while :; do
# Assuming you want to show the menu before you start a program:
bash showMenu.py
python myScript.py
# When the above scripts exits the process will start all over again
# You might want to consider checking the exit code and only continue if the program exits with status code 0
# [ $? gt 0 ] && break
done

Python script embedded in shell script, does not exit and daemon solution does not fit the needs

This question extends/revives this one.
The relevance to revive this topic is due to the failure in solving the same problem with the given answers.
The bash script executes a python script embedded. Something like
#!/bin/bash
./pyscript.py
chmod +x pyscript.py permission was given.
Alternative ways to run the script were used.
(python -u pyscript.py or /usr/bin/python pyscript.py)
As the title states the python program does not exit.
I have tried the following attempts within the python script to solve the issue:
sys.exit(0); %the program catches the correct exception
os._exit(1) %does not work and the correct exception is catched
sys.stdout.flush() %to clean the buffer of the stdout
The daemon solution is not suitable for what I need, because running in the background independently from the main script will not wait for the execution of the python program untill the end.
What are the alternative solutions that remain for this case?
Have you tried to use strace -p $PID on the python process? The output will not always be useful however.
From the code perspective, in addition to threads I would check if there are any signal handlers (which maybe do not terminate for some reason).
As far as threads are concerned, you might be interested in this, although I believe someone mentioned it in the other thread.
Finnally the problem is solved.
The program in python wich I've been trying to kill the process runs with multiple threads.
sys.exit(0) only terminates the thread in which the program is called.
The os._exit(1) was called with the sys.exit(0) before its execution (fail!).
By running os._exit(1) without sys.exit(0) before, the program exit the python script.
The reason must be that sys.exit() only terminates the thread in which it is called and allows the program to clean resources, while os._exit() does an abrupt program termination.
Found here.
With this solution it's better guarantee the termination of any task the program should end and then call os._exit.
what I usually do to separate a script from the main shell terminal process is sending the script inside a screen session detached. Then I kill the pid of the script without any trouble.
But for this particular case I want the program waiting for the end of the python subscript and not as a parallel process.
Also, you might want to try the trace module, i.e. running your program with #!/usr/bin/env python -m trace --trace. If python is executing some of your code (which it probably is), it should show you details on that.

"script command" and logging in python

I have a python app that has lots of outputs on the screen which can be used for debugging. out of all the logging techniques, "script" command works well for me because I can see the output on the screen as well as logging it. I want to include that at the beginning of my python app to run automatically and log everything, when I do, however, the python program doesn't run. as soon as I type exit at the terminal (which stops script logging) the app starts working. The command I'm using is:
command="script /tmp/appdebug/debug.txt"
os.system(command)
I have also tried script -q but the same issue is there. Would appreciate any help.
Cheers
Well, I did find the answer for anyone who is interested:
https://stackoverflow.com/questions/15507602/logging-all-bash-in-and-out-with-script-command
and
Bash script: Using "script" command from a bash script for logging a session
I will keep this question as others might have the same issue and finding those answers wasn't exactly easy :)
Cheers
Try to use subprocess, like so:
from subprocess import Popen, PIPE
p = Popen(['script', '/tmp/appdebug/debug.txt'], stderr=PIPE, stdout=PIPE)
stdout, stderr = p.communicate()
script is a wrapper for a session of interactions. Even if it appears to terminate quickly after being started in a shell, this is not so; instead it starts a new shell in which you can interact so that everything is logged to a file.
What does this mean for you?
Your approach of using script cannot work. You start script using os.system which will wait for script to terminate before the next Python statement is executed. script's work will only happen before it terminates (i. e. during the uninteresting waiting period of your Python program).
I propose to use script -c yourprog.py yourprog.log instead. This will execute and wrap the yourprog.py and the session will be stored in yourprog.log.

python script exits when a shell command(to terminate a different tool) is run from os.system()

I am running a shell command from within my python script using
os.system("some shell command")
This command essentially terminates a tool.
I need to check that this tool is terminated in my script.
But as soon as the tool is terminated the script is terminated too!
Is the script, by any chance, launched by that same tool? If yes, you need to run os.setsid() to stop being dependent on it.
Your script is probably terminating correctly. Try adding the following line after your last line of code to illustrate to you that it is done.
raw_input('Press any key to exit.')

Categories