[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