13

I want to create a script that runs when a Zsh instance starts, but only if the instance is:

  • Non-login.
  • Interactive

I think I'm right to say .zshrc runs for all interactive shell instances, .zprofile and .zlogin run for all login shells, and .zshenv runs in all cases.

The reason I want to do this is to check if there is an existing ssh-agent running, and make use of it in the newly opened shell if there is.

I imagine any tests carried out would be best placed in .zshrc (as this guarantees an interactive shell) and the designated "non-login event" script called from there.

I probably first want to check if the new shell is already running as part of an existing remote SSH session before testing for the ssh-agent, but I have found this SE recipe for this purpose.

I pick Zsh as it is the shell I favor, but I imagine any correct technique to do this would apply similarly to other shells.

Geeb
  • 2,061
  • 2
  • 16
  • 17

1 Answers1

26
if [[ -o login ]]; then
  echo "I'm a login shell"
fi

if [[ -o interactive ]]; then
  echo "I'm interactive"
fi

[[ -o the-option ]] returns true if the-option is set.

You can also get the values of options with the $options special associative array, or by running set -o.

To check if there's an ssh-agent:

if [[ -w $SSH_AUTH_SOCK ]]; then
  echo "there's one"
fi

In ksh (and zsh):

case $- in (*i*) echo interactive; esac
case $- in (*l*) echo login; esac

In bash, it's a mess, you need:

case $- in *i*) echo interactive; esac # that should work in any Bourne/POSIX shell
case :$BASHOPTS: in (*:login_shell:*) echo login; esac

And $SHELLOPTS contains some more options. Some options you can set with set -<x>, some with set -o option, some with shopt -s option.

Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
  • Right ... I had noticed these `-o` options but I thought they were options that were set-able to _override the defaults_ i.e. to _force behavior_, rather than to query the actual situation. Am I wrong? – Geeb Jan 24 '14 at 11:24
  • @Geeb, `[[ -o opt ]]` checks if `opt` is set. I can't see why it would do it only when the option is set some way and not the other. – Stéphane Chazelas Jan 24 '14 at 12:10
  • So you're saying querying the option values always reports the truth of the matter? e.g. you couldn't trick a shell instance, started in a non-interactive mode, into reading `.zshrc` by setting the `interactive` option? – Geeb Jan 24 '14 at 12:38
  • The `.zshrc` is read _on startup_ when the shell is interactive. It may be read by someone doing `source ~/.zshrc`. – Stéphane Chazelas Jan 24 '14 at 12:49
  • OK a different type of deception: Setting the `login` option in `.zshrc` would cause all interactive shells started after this change to behave as though they were a result of a login, right? i.e. the behavior is forced - in truth they are not really login shells, and only behave as such because they have been told to be so by the authority of the option setting? – Geeb Jan 24 '14 at 14:09
  • @Geeb, yes, if your users may do anything silly, then they could also redefine `echo` as an alias that tells you the reverse of what you tell it to. I'm not sure I can see where you're getting at. – Stéphane Chazelas Jan 24 '14 at 14:20
  • I think what I'm asking is: Are these settings options or parameters? If you read the `login` option as true, but is a result of a forced setting, you have surely been deceived? _Sorry to make such a big deal out of this, I'm just trying to understand!_ – Geeb Jan 24 '14 at 14:23
  • @Geeb, if you do `setopt login`, then you want your shell to become a `login` shell. That doesn't really make sense (except maybe if you want your `.zlogout` to be interpreted on exit), but if you've got something that should be run on login shells, then it seems to me that it's right to have it done after you `setopt login`. – Stéphane Chazelas Jan 24 '14 at 14:34
  • It seems `interactive` [is not set-able](http://zsh.sourceforge.net/Guide/zshguide02.html) but you can obviously test for it. So this "option" does seem to actually be a _parameter_. – Geeb Jan 24 '14 at 15:26