0

I have a third-party shell function that's trying to use tty -s to detect whether it's called from an interactive shell, but reports that it's in an interactive shell even when it isn't.

#!/usr/bin/env bash

get_shell_type() {
    tty -s && echo "INTERACTIVE" || echo "NON-INTERACTIVE"
}

Why is this expected to work? How can I fix it?

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Chan Kim
  • 5,177
  • 12
  • 57
  • 112
  • 1
    This is an attempt to detect whether the shell is interactive or not. – Cyrus Dec 12 '20 at 13:52
  • yes, I can guess that, but I can't understand how it does that. When I call get_shell_type in that same script, it returns "INTERACTIVE" when it's not. – Chan Kim Dec 12 '20 at 13:54
  • 1
    I suggest with `bash`: `[[ $- =~ i ]] && echo "INTERACTIVE" || echo "NON-INTERACTIVE"` – Cyrus Dec 12 '20 at 13:55
  • 2
    Does `man tty` tell you? – Shawn Dec 12 '20 at 13:55
  • If it doesn't work, it _doesn't_ do the intended thing, so why guess at the how? Buggy code is, well, buggy; its authors were mistaken, not successfully accomplishing some hidden purpose. It would make more sense to ask how to accomplish the stated purpose correctly than to ask why the wrong code is expected to work (a question that asks us to speculate about what was in its authors' heads). – Charles Duffy Dec 12 '20 at 14:00
  • _nod_. This is closer to "is this being run with its output displaying in an interactive terminal?" than "is this being run from an interactive shell?". – Charles Duffy Dec 12 '20 at 14:03
  • 1
    I’m voting to close this question because it calls for speculation on what someone else was thinking. Nobody but the original author knows definitively what their intent was, and why they wrote this (buggy) code instead of a correct implementation. – Charles Duffy Dec 12 '20 at 14:09

1 Answers1

0

This could be an attempt to determine whether output is being written to an interactive terminal, not whether the shell itself is interactive.

If so, it is a slower/less-efficient/buggier equivalent to the following:

get_shell_type() {
  if [[ -t 0 ]]; then echo INTERACTIVE; else echo NON_INTERACTIVE; fi
}

If the goal is to determine whether a shell is interactive, it's simply wrong.

Whether a shell is interactive is influenced by whether its stdin is connected to a TTY (as a heuristic used to guess in situations where it isn't clear), but the final decision after all the heuristics are done is reflected in whether set -i is active. Like all other set flags, the active ones can be seen in $-. Thus:

get_shell_type() {
  case $- in *i*) echo "INTERACTIVE";; *) echo "NON-INTERACTIVE";; esac
}

See also:

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441