Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I think I understand the differences between an interactive, a login and a batch shell. See the following links for more help:

My question is, how can I test with a command/condition if I am on an interactive, a login or a batch shell?

I am looking for a command or condition (that returns true or false) and that I could also place on an if statement. For example:

if [[ condition ]]
   echo "This is a login shell"
fi
share|improve this question
    
There is yet another question: Are STDIN and/or STDOUT connected to a tty (terminal) or a pipe (file or process)? This is a related but distinct test as described in some of the below comments. –  Mark Hudson Oct 10 at 18:04

5 Answers 5

up vote 37 down vote accepted

I'm assuming a bash shell, or similar, since there is no shell listed in the tags.

To check if you are in an interactive shell:

[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'

To check if you are in a login shell:

shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'

By "batch", I assume you mean "not interactive", so the check for an interactive shell should suffice.

share|improve this answer
1  
For zsh users, checking for a login shell can be done with: if [[ -o login ]] ... –  chb Jun 27 '13 at 5:05
1  
If you want to know if a "user" ran your program versus "cron". [[ TERM=="dumb" ]] && echo "Running in cron. –  Erik Aronesty Dec 3 '13 at 17:49
3  
@ErikAronesty Not all dumb terminals are cron sessions. –  Chris Down Dec 4 '13 at 22:11

In any Bourne-style shell, the i option indicates whether the shell is interactive:

case $- in
  *i*) echo "This shell is interactive";;
  *) echo "This is a script";;
esac

There's no portable and fully reliable way to test for a login shell. Ksh and zsh add l to $-. Bash sets the login_shell option, which you can query with shopt -q login_shell. Portably, test whether $0 starts with a -: shells normally know that they're login shells because the caller. This fails to detect shell-specific ways of invoking a login shell (e.g. ash -l).

share|improve this answer

csh / tcsh

For csh and tcsh I have the following in my .cshrc file:

if($?prompt) then               # Only interactive shells set $prompt
    ...
endif

Specifically for tcsh, the variable loginsh is set for a login shell:

if($?loginsh) then              # A login shell..
    ...
endif

(tcsh also has a variable shlvl which is set to the number of nested shells, where the login shell has a value of 1.)

share|improve this answer
    
PS1 does not work to test for an interactive shell. It's almost always set in an interactive, but you can unset it. It's very often set in a noninteractive shell, because many systems ship with export PS in /etc/profile. –  Gilles Dec 14 '11 at 11:35
    
@Gilles Thank you for the correction and edit –  Andrew Stein Dec 14 '11 at 15:26

Another way is to check the result of tty

if [ "`tty`" != "not a tty" ]; then
share|improve this answer
4  
... or use [ -t 0 ] to test if STDIN is a tty. You can also use 1 (STDOUT) or 2 (STDERR) depending on your needs. –  derobert Dec 13 '11 at 23:17
    
@derobert - thanks for showing me something new –  Adrian Cornish Dec 14 '11 at 3:12
4  
This is a different test. It is possible to have a noninteractive shell whose input is a terminal (anytime you run a script in a terminal!), and it is possible (albeit rare) to have an interactive shell taking input not from a terminal. –  Gilles Dec 14 '11 at 11:34
    
@Gilles if the shell was interactive, and closed leaving a child disown and alive, tty worked best to know it is not interactive anymore, while $- did not change; I am still puzzled about what is the best approach. –  Aquarius Power Jul 25 at 6:14
2  
@AquariusPower Then what you want to test is not for an interactive shell, but whether standard input is a terminal. Use [ -t 0 ]. P.S. In my previous comment, I wrote that “there's a strong correlation” — I forgot “apart from the extremely common case of a script started with #!/bin/sh or the like”, which is non-interactive but can be connected to a terminal. –  Gilles Jul 25 at 7:55

Take a look at the shopt command (at least for Bash). That can definitely tell you if you're in a login shell. I don't know about interactive/batch.

Reference: http://www.linuxquestions.org/questions/programming-9/how-to-check-in-a-script-whether-the-shell-is-login-or-non-login-360629/

Look in the Bash man page for more info: http://linux.die.net/man/1/bash

Note: I am giving you Bash, since that's what I know. Presumably other shells have similar functionality.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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