36.1. Interactive and non-interactive shells and scripts
An interactive shell reads commands from user input on a tty . Among other things, such a shell reads startup files on activation, displays a prompt, and enables job control by default. The user can interact with the shell.
A shell running a script is always a non-interactive shell. All the same, the script can still access its tty . It is even possible to emulate an interactive shell in a script.
#!/bin/bash MY_PROMPT=’$ ‘ while : do echo -n «$MY_PROMPT» read line eval «$line» done exit 0 # This example script, and much of the above explanation supplied by # St�phane Chazelas (thanks again).
Let us consider an interactive script to be one that requires input from the user, usually with read statements (see Example 15-3 ). «Real life» is actually a bit messier than that. For now, assume an interactive script is bound to a tty, a script that a user has invoked from the console or an xterm .
Init and startup scripts are necessarily non-interactive, since they must run without human intervention. Many administrative and system maintenance scripts are likewise non-interactive. Unvarying repetitive tasks cry out for automation by non-interactive scripts.
Non-interactive scripts can run in the background, but interactive ones hang, waiting for input that never comes. Handle that difficulty by having an expect script or embedded here document feed input to an interactive script running as a background job. In the simplest case, redirect a file to supply input to a read statement ( read variable
If a script needs to test whether it is running in an interactive shell, it is simply a matter of finding whether the prompt variable, $PS1 is set. (If the user is being prompted for input, then the script needs to display a prompt.)
if [ -z $PS1 ] # no prompt? ### if [ -v PS1 ] # On Bash 4.2+ . then # non-interactive . else # interactive . fi
Alternatively, the script can test for the presence of option «i» in the $- flag.
case $- in *i*) # interactive shell ;; *) # non-interactive shell ;; # (Courtesy of «UNIX F.A.Q.,» 1993)
However, John Lange describes an alternative method, using the -t test operator .
# Test for a terminal! fd=0 # stdin # As we recall, the -t test option checks whether the stdin, [ -t 0 ], #+ or stdout, [ -t 1 ], in a given script is running in a terminal. if [ -t «$fd» ] then echo interactive else echo non-interactive fi # But, as John points out: # if [ -t 0 ] works . when you’re logged in locally # but fails when you invoke the command remotely via ssh. # So for a true test you also have to test for a socket. if [[ -t «$fd» || -p /dev/stdin ]] then echo interactive else echo non-interactive fi
Scripts may be forced to run in interactive mode with the -i option or with a #!/bin/bash -i header. Be aware that this can cause erratic script behavior or show error messages even when no error is present.
what is INTERACTIVE unix shell
I have been trying to understand what does it mean by ‘interactive’ shell. I have read a lot of material on net as well as gone thru the man pages — INVOCATION section. So in particular I would like to put up some simple questions : 1) How do I start a non-interactive shell ? Is it by saying ‘bash —login’ ? 2) I just could not make out what additional could I do in an interactive shell that I can not do in a shell script (all this material keeps saying that shell script would run in a non-interactive shell) 3) When I start a terminal in a GUI, is the shell that runs there be an non-login interactive shell 4) can I run a shell script in an interactive shell
1 Answer 1
As explained in the Bash manual:
An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option. PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state.
1) How do I start a non-interactive shell ? Is it by saying ‘bash —login’?
Basically most of the time you can do it by running the shell with a script, or running the shell with the -c option. If the shell does not run with a script and if the shell gets its input redirected, the shell would automatically exit if the input ends.
2) I just could not make out what additional could I do in an interactive shell that I can not do in a shell script (all this material keeps saying that shell script would run in a non-interactive shell)
There isn’t much difference only that the prompt is naturally not shown. Job control is also not enabled. It’s only when Bash is executed interactively that it runs the rc file ~/.bashrc . Basically the shell would try to behave the way it should when not interacting with a terminal to make it work correctly and not hang somewhere else.
3) When I start a terminal in a GUI, is the shell that runs there be an non-login interactive shell
It certainly is an interactive shell at least by default.
4) can I run a shell script in an interactive shell
If you mean with the current shell itself, yes with . or source . The prompt returns when the shell script ends.
What are the differences between a login shell and interactive shell?
An interactive shell is one started without non-option arguments, unless -s is specified, without specifying the -c option, and whose input and error output are both connected to terminals (as determined by isatty(3)), or one started with the -i option.
An interactive shell generally reads from and writes to a user’s terminal.
A login shell is a shell where you login. You can recognize a login shell from a ps -f listing, it will have a hyphen at the start of the program name, for example:
root 3561 3553 0 09:38 pts/0 00:00:00 -bash qa 7327 3432 0 10:46 pts/1 00:00:00 -bash
An interactive shell is one which reads commands from its standard-input, usually a terminal.
- if you login to bash using an xterm or terminal emulator like putty , then the session is both a login shell and an interactive one.
- if you then type bash then you enter an interactive shell, but it is not a login shell.
If a shell script (a file containing shell commands) is run, then it is neither a login shell nor an interactive one.
Start-up files are highly tailorable in bash:
When a login bash shell is invoked, then /etc/profile is sourced (executed in the current environment). After that, three files are checked for existence. The checks for these files are done in this order, the first one that exists is run.
Once a match is found, the other files are ignored, even if they exist. The /etc/bashrc file might be used by both the ~/.bash_profile and the ~/.bashrc files. That would mean that the /etc/bashrc file is sourced on all interactive invocations of bash, whether it is a login or non-login shell.
So, the .bashrc file is also run every time you request a new interactive shell. This does not include a shell script. Normally variables, aliases or functions are placed in this file.
Bash shell scripts read a different file if suitably instructed. If the user defines (usually in their own .bash_profile ) a variable BASH_ENV which contains a filename, scripts will read this. If this variable is not set (and exported) then bash scripts will not read any startup files.
what do you mean by interactive shell?
You can start another shell after you log in by using the name of the shell as a command; for example, to start the Korn shell, you could type ksh at the command prompt. This type of shell is not a login shell, and you do not have to log in again to use it, but it is still an interactive shell, meaning that you interact with the shell by typing in commands (as opposed to using the shell to run a script, as discussed in Chapter 20). The instances of the shell that run in a terminal window when you are using a graphical interface are also interactive non-login shells. When you start a non-login shell, it does not read your .profile, .bash_profile, or .login file (or your .logout file), but it will still read the second shell configuration file (such as .bashrc). This means that you can test changes to your .bashrc by starting another instance of the shell, but if you are testing changes to your .profile or .login, you must log out and then back in to see the results.
I was going through above lines and I don’t understand what it means by interactive shell. Is it true that .profile is not read if I am using terminal? Moreover, what does it mean when you say that bourne is not is an interactive shell while bash/csh is an interactive shell?
1 Answer 1
An interactive shell is simply any shell process that you use to type commands, and get back output from those commands. That is, a shell with which you interact.
So, your login shell is interactive, as are any other shells you start manually, as described in the excerpt you quoted in your question. By contrast, when you run a shell script, a non-interactive shell is started that runs the commands in the script, and then exits when the script finishes.
The Bourne shell can be used as an interactive shell, just like bash or tcsh . In fact, many systems, such as FreeBSD, use sh as the default user shell. Modern shells like bash , zsh , tcsh , etc have many features that Bourne shell doesn’t have, that make them more comfortable and convenient for interactive use (command history, completion, etc).
Interactive non-login shells (that is, shells you start manually from another shell or by opening a terminal window) don’t read your .login or .profile files. These are only read and executed by login shells (shells started by the login system process, or by your X display manager), so the commands and settings they contain are only applied once, at the beginning of your login session. So, when you start a terminal, the shell that it spawns for you does not read your login files ( .login for c-style shells, .profile for bourne style shells), but it does read the .cshrc , .bashrc etc files.