3

The -s option to bash doesn't seem to really do anything

When I execute commands with or without it nothing changes. What really confuses me is when I execute a shell script I always seem to be getting an interactive shell. I'm assuming it's interactive because when I use the read builtin in the script it will always prompt me for input. Does this make it interactive?

Do shell script run as interactive in fedora, and are there any examples of a difference that the -s can make? I have read the man pages, but can't seem to generate any examples on my own that would have any effect. I combined the two questions because I was trying to use s to change how the script received input, and in some tutorials they say it has an effect. I realize that it can set arguments, what I don't get is how it changes it to read from standard input it always seems to do that anyway

Here is what I used to test it

if [ -v $PS1 ]
then
  echo non-interactive
else
  echo interactive
fi
read ; echo $REPLY

read was always able to work in both non and interactive shells

Even when I tested for the presence of fd/0 and fd/1 in non-interactive shells they still existed

Thanks in advance

4 Answers 4

5

Bash will also determine whether or not it is interactive by examining if its input/output are attached to a terminal.

The -s non-interactive switch allows the bash script to process positional parameters when reading commands from a file. eg:

$ cat demo.sh
echo '$0 = ' $0
echo '$1 = ' $1
echo '$2 = ' $2

$ bash < demo.sh foo bar
bash: foo: No such file or directory

$ bash -s < demo.sh foo bar
$0 =  bash
$1 =  foo
$2 =  bar
4

The -s option causes bash to read commands from its standard input. Without this option, bash treats its first argument as the name of a script to execute. With this option, bash treats all of its arguments as arguments to the script that it reads on standard input. The -s option only determines how bash interprets its command line arguments, not whether the shell instance is interactive.

An instance of bash is always interactive if it is started with the -i option. Without -i, it is interactive only if no script name is passed (-s influences this) and both standard input and standard error are connected to a terminal.

Testing PS1 does not tell you whether a shell instance is interactive.¹ You can unset PS1 in an interactive shell. Conversely, a non-interactive shell often inherits PS1 from its environment. The reliable way to test if the shell is running interactively is to test if $- contains i.

The read builtin works from any shell, interactive or not. It reads from whatever is connected to the shell's standard input (unless redirected). If you try to read from the same file descriptor where bash is reading the script it's executing, you'll end up skipping a line in the script (not necessarily at the place you intended); for example, if you're passing a script on bash's standard input and you want to read a line from the terminal, you need to redirect the read call: read line </dev/tty.

File descriptors 0, 1 and 2 always exist (unless they've been closed); they are standard input, standard output and standard error respectively. Whether the shell is interactive or not is unrelated to what the standard descriptors point to, except that whether fd 0 and 2 are terminals influences the shell's interactive status.

¹ Yes, I'm aware that there are web pages that claim this. They're wrong.

2

A little more info on interactive shells:

You can find out whether a shell is interactive or not by checking $-. If $- contains an i, then the shell is interactive.

A shell is interactive when it reads the input from the user directly. A non-interactive shell reads commands from a file line by line and executes them. It doesn't make the shell interactive when reading anything from stdin from within the script, as "the script reads the input, not the shell" (don't know how to explain this any better).

    labdebian# cat ./test
    #!/bin/bash
    echo Hello World
    echo $-
    read; echo $REPLY
    echo $-

    labdebian# bash test
    Hello World
    hB
    I'm typing this
    I'm typing this
    hB

    labdebian# bash -i test
    Hello World
    himB
    I'm typing this
    I'm typing this
    himB
1
  • What was confusing is in the the documentation for bash they say it will hang if you use read in a non - interactive shell
    – rubixibuc
    Dec 27, 2011 at 2:15
0

-s doesn't make your shell interactive. Use -i instead.

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.