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.

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

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

[[ -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"

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.

  • 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.