I have a python3 script which I run from console. When I try to run it detached from console using
- script.py & disown -f
- setsid -f script.py
then I close the console, the script crash after a while.
If I detach it using:
- nohup script.py &
- at now
script.py
Ctrl+D
it keeps running.
Script sleep, wake up every 10s do Some processing, print some output.
I discovered the script is crashing because of print()
.
When I comment out the lines with print()
, it run without problems
when I detached it from console and console is closed.
I solved this by using logging module:
logging.basicConfig(format='%(message)s', encoding='utf-8', level=logging.INFO,handlers=[logging.StreamHandler(sys.stdout)])
and replace print()
with logging.info()
So, stdout is "closed"/"invalid" when the script is detached from console using first 3 methods then console is closed. I knew that but I did not know will affect python, bash script don't care about it. 4th method does not close stdout, the output is sent on mail, so that's why it works.
I am curious how can I check in this situation if it is safe to write to stdout, using print()
or sys.stdout.write()
?
I tried both of these conditions
if sys.stdout.closed==False
if sys.stdout is not None
but print() is still called when the script is detached from console using above first 2 methods, then console is closed.
#!/usr/bin/python3
import time
import sys
for i in range(1,100):
# same result
#if sys.stdout.closed==False
if sys.stdout is not None
print(str(i))
time.sleep(10)
sys.stdout.writable
return true when script.py is detached from terminal using 1. and 2. and calling print(
) crash the script.
But I found that I can check if script is still connected to tty with:
if sys.stdout.isatty() :
print(...)
this works to avoid print()
when script is detached from tty.