Under Ubuntu Desktop (Unity) when a script marked as executable and then I click on the file I get pop-up window like the one here in the image:
pyscript.py is an executable Python script file with a shebang: #!/usr/bin/python
where /usr/bin/python is the path to the Python interpreter. Since I'm not running this process in a terminal window, because I just clicked "Run", I thought initially there would be no standard streams for the process; As I experimented more, I realized all the standard streams are available:
pyscript.py
#!/usr/bin/python3
import sys, os
f = file=open("output.txt", "w")
print(sys.stdout, sys.stdin, sys.stderr, sep='\n', file=f)
output.txt
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>
<_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>
Which raises the question, there's no terminal window running in the background, what are sys.stdout, stdin and stderr connected to? Technically, running Python without console window under Windows with .pyw I get the same output.
Take a look at this question: pythonw.exe or python.exe?
One answer states the following:
Standard streams
sys.stdin
,sys.stdout
andsys.stderr
are NOT available.
The emphasis that standard streams are not available doesn't seem to be true when I test this with Python 2.7 in Windows 10 by clicking the .pyw file, though, in the Windows registry .pyw files are associated with Python 2.X which runs pythonw.exe in my machine.
This question is a Unix/Windows jumble!
The standard streams are simply preopened Python file objects that are automatically connected to your program's standard streams when Python starts up. By default, all of them are tied to the console window where Python (or a Python program) was started.
To change the terminal controls in the Unix system, we can use the tty related methods in Python. Using the tty module, we can set two different modes of the terminal. The raw Mode and the cbreak mode.
As others mentioned, the question is not Python-specific. When a process is spawned, it's the parent's duty to set the child's file descriptors (or to allow them to be inherited).
So, this is not even OS-specific, but actually application specific. For example, you might have a different anser for Gnome and KDE. Or when executing the file from within Windows Explorer or 7-Zip (I think; I know how this works on Unix, not so sure on Windows). Different applications spawning the process might be making different arrangements.
On Linux, you can find out by running lsof
on the python process, which will list the opened files and tell you where exactly your stdout is going. Here's your code, changed to do just that:
#!/usr/bin/env python
# vi: ai sts=4 sw=4 et
import sys, os, pprint
import subprocess
f = open("/tmp/output.txt", "w")
for stream in (sys.stdout, sys.stdin, sys.stderr):
print (stream, file=f)
print ("STTY?", stream.isatty(), file=f)
print ("fileno:", stream.fileno(), file=f)
print ("name:", stream.name, file=f)
# print (pprint.pprint(dir(stream)), file=f)
print (file=f)
subprocess.call ("lsof -p %s" % os.getpid(), stdout = f, shell = True)
Only the last line is actually important. See the output for a normal run:
(...)
test.py 29722 xxx 0u CHR 136,4 0t0 7 /dev/pts/4
test.py 29722 xxx 1u CHR 136,4 0t0 7 /dev/pts/4
test.py 29722 xxx 2u CHR 136,4 0t0 7 /dev/pts/4
And when redirecting the output to a file:
(...)
test.py 29728 xxx 0u CHR 136,4 0t0 7 /dev/pts/4
test.py 29728 xxx 1w REG 0,38 0 2070222 /tmp/asdf.txt
test.py 29728 xxx 2u CHR 136,4 0t0 7 /dev/pts/4
See that the file #1 has changed? Same will happen when you run it from Unity, telling you where that is going.
I didn't exactly reproduce your problem, as my Gnome 3 file manager won't run scripts like that and I'd not look into it, but I'm curious to know where yours goes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With