help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] Detecting shell type (ie: is/non interactive/ssh/login s


From: Bob Proulx
Subject: Re: [Help-bash] Detecting shell type (ie: is/non interactive/ssh/login shell)
Date: Fri, 9 Sep 2016 16:22:49 -0600
User-agent: NeoMutt/ (1.7.0)

Matthew Giassa wrote:
> I'm working on a modified (GPL'ed of course) version of guake and
> konsole to provide some additional UX features depending on what type of
> shell is currently being used. IE: when in interactive mode, a green
> light icon is illuminated; while running a script or lengthy command via
> "bash -c" an amber light icon is lit; if a remote session is launched in
> a special manner, other features kick in, etc.

Where will this indicator light be displayed?  Are you thinking the
script will communiate with some notifier daemon in a desktop system
tray?  How will this communication be accomplished?  Something like
the notify-send(1) program?

> The parameters I am primarily concern with is the type of shell being
> launched, ie:
> 
> * Interactive or not (ie: "bash" versus "bash -c" or ". test.sh").
> * Login shell or not.
> * SSH-initiated (ie: remote) shell or not.

First let me say that I think this is a bad idea.

However if you are really wanting to know in a script if it is
interactive or not a typical way is to look to see if stdin is
connected to a tty device or not.  That isn't a complete guarentee but
it is a typical way to do things different if a script is running from
the command line attached to a user's keyboard or if it is being run
from cron where the input is redirected from /dev/null.

  if [ -t 0 ]; then
    echo "This script is interactive."
  else
    echo "This script is not interactive."
  fi

> I am able to calculate these values via the following simple script,
> which I've put in /etc/bash.bashrc on my Ubuntu test system:
> 
>     #!/bin/bash
>     BASH_ENV=/etc/bash.bashrc # Needed so the non-interactive shells

Setting BASH_ENV like this is a very bad thing to do.

It is non-portable.  It depends upon your local system shipping a
/etc/bash.bashrc file and only some do.  It sets a BASH_ENV that bash
is required to load which is meant for interactive shells but will now
be loaded for non-interactive shells.  I can't imagine anything in
/etc/bash.basrc that I would want to have in a non-interactive shell.
It will be a slowdown due to the need to read and process that file.

Don't do it.  Seriously.  It's a bad idea.

>     if [[ $- == *i* ]]; then
>       echo "interactive"
>     else
>       echo "non-interactive"
>     fi

That doesn't seem too scary.  But the only place I have ever needed to
do anything like this is in the ~/.bashrc and/or .profile files.  I
have never needed to do this anywhere else.

>     if shopt -q login_shell ; then
>       echo "login"
>     else
>       echo "non-login"
>     fi

Same thing here only more so.  You really shouldn't ever encounter a
login shell outside of the login environment of .profile and .bashrc
and friends.  Regular scripts should not care.  So looking for this is
just road best not taken.

>     # Detect whether or not this is an SSH-controlled session.
>     if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then
>       echo "ssh"
>     else
>       case $(ps -o comm= -p $PPID) in
>       sshd|*/sshd)
>               echo "ssh"
>               ;;
>       *)
>               echo "non-ssh"
>               ;;
>       esac
>     fi

This also is something that seems undesirable to need to know.

> I was originally planning on having the modified guake/konsole
> application detect a special string which would be generated by the
> above script, but that approach appears to be doomed to failure as the
> extra output generated for non-interactive shells will break sftp, scp,
> etc. I've also looked into using bash-preexec
> (https://github.com/rcaloras/bash-preexec), but using it in
> non-interactive shells is risk prone, as noted by the author
> (https://github.com/rcaloras/bash-preexec/issues/25).

I also think setting up an LD_PRELOAD for this is not the thing to do
but even more so than BASH_ENV.  Since it is interacting with the
program at a deeper level.  It just goes further down the wrong direction.

> Within the BASh source itself, which I've just started diving in to, is
> there any way to query all three of the above values prior to calling
> `execute_command` (execute_cmd.c)? If so, I could either provide a
> modified BASh or use LD_PRELOAD to wrap the call and send data over a
> pipe to the guake/konsole application to know what type of shell is in
> use.

I think you are going the wrong direction.  Instead of having one
script that is called in multiple different ways you should have
different scripts for different tasks.  A script program being called
interactively from the command line can interact with system tray
notification.  A script program running by a daemon or cron that is
not interactive can be designed from the start to be non-interactive.
Then there is no problem to be solved. :-)

Bob



reply via email to

[Prev in Thread] Current Thread [Next in Thread]