narnie
narnie

Reputation: 1772

How to tell if python script is being run in a terminal or via GUI?

I'm working in Linux and am wondering how to have python tell whether it is being run directly from a terminal or via a GUI (like alt-F2) where output will need to be sent to a window rather than stdout which will appear in a terminal.

In bash, this done by:

if [ -t 0 ] ; then  
    echo "I'm in a terminal"
else
    zenity --info --title "Hello" --text "I'm being run without a terminal"
fi

How can this be accomplished in python? In other words, the equivalent of [ -t 0 ])?

Upvotes: 14

Views: 8193

Answers (5)

WinEunuuchs2Unix
WinEunuuchs2Unix

Reputation: 1929

In bash I use this script:

$ cat ~/bin/test-term.sh

#!/bin/bash

#See if $TERM has been set when called from Desktop shortcut

echo TERM environment variable: $TERM > ~/Downloads/test-term.txt
echo "Using env | grep TERM output below:" >> ~/Downloads/test-term.txt
env | grep TERM >> ~/Downloads/test-term.txt

exit 0

When you create a desktop shortcut to call the script the output is:

$ cat ~/Downloads/test-term.txt

TERM environment variable: dumb
Using env | grep TERM output below:

Notice grepping env command returns nothing?

Now call the script from the command line:

$ cat ~/Downloads/test-term.txt

TERM environment variable: xterm-256color
Using env | grep TERM output below:
TERM=xterm-256color

This time the TERM variable from env command returns xterm-256color

In Python you can use:

#import os
result = os.popen("echo $TERM")
result2 = os.popen("env | grep TERM")

Then check the results. I haven't done this in python yet but will probably need to soon for my current project. I came here looking for a ready made solution but noone has posted one like this yet.

Upvotes: 1

thebeak
thebeak

Reputation: 11

I had the same issue, and I did as follow:

import sys

mode = 1
try:
    if sys.stdin.isatty():
        mode = 0
except AttributeError:  # stdin is NoneType if not in terminal mode
    pass

if mode == 0:
    # code if terminal mode ...
else:
    # code if gui mode ...

Upvotes: 1

Six
Six

Reputation: 5502

I scoured SE for an answer to this but everywhere indicated the use of sys.stdout.isatty() or os.isatty(sys.stdout.fileno()). Neither of these dependably caught my GUI test cases.

Testing standard input was the only thing that worked for me:

sys.stdin.isatty()

Upvotes: 2

Gaius
Gaius

Reputation: 2585

There are several examples of this on PLEAC which counts for a third case: running at an interactive Python prompt.

Upvotes: 0

Alex Martelli
Alex Martelli

Reputation: 881477

$ echo ciao | python -c 'import sys; print sys.stdin.isatty()'
False

Of course, your GUI-based IDE might choose to "fool" you by opening a pseudo-terminal instead (you can do it yourself to other programs with pexpect, and, what's sauce for the goose...!-), in which case isatty or any other within-Python approach cannot tell the difference. But the same trick would also "fool" your example bash program (in exactly the same way) so I guess you're aware of that. OTOH, this will make it impossible for the program to accept input via a normal Unix "pipe"!

A more reliable approach might therefore be to explicitly tell the program whether it must output to stdout or where else, e.g. with a command-line flag.

Upvotes: 10

Related Questions