本文为 Bash Reference Manual第6章:Bash Features 第3节:[Interactive Shells](https://www.gnu.org/software/bash/manual/bash.html#Interactive-Shells 的读书笔记。
完整的笔记目录参见Bash学习笔记总目录。
6.3 Interactive Shells
6.3.1 What is an Interactive Shell?
交互式 shell 是在没有非选项参数启动(除非指定了 -s)并且未指定 -c 选项的情况下启动的,其输入和错误输出都连接到终端(由 isatty(3) 确定),或者是在使用 -i 选项启动的情况下启动的。
交互式 shell 通常从用户的终端读取输入并输出内容。
启动交互式 shell 时,可以使用 -s 调用选项来设置位置参数。
6.3.2 Is this Shell Interactive?
要在启动脚本中判断 Bash 是否以交互模式运行,可以测试特殊参数 '-' 的值。当 shell 处于交互模式时,它包含 i。例如:
bash
case "$-" in
*i*) echo This shell is interactive ;;
*) echo This shell is not interactive ;;
esac
示例:
bash
$ echo $-
himBHs
$ cat isix.sh
case "$-" in
*i*) echo This shell is interactive ;;
*) echo This shell is not interactive ;;
esac
$ bash -c ./isix.sh
This shell is not interactive
或者,启动脚本可以检查变量 PS1;在非交互式 shell 中该变量未设置,在交互式 shell 中则已设置。因此:
bash
if [ -z "$PS1" ]; then
echo This shell is not interactive
else
echo This shell is interactive
fi
6.3.3 Interactive Shell Behavior
当 shell 以交互模式运行时,它会以多种方式改变其行为。
- Bash 会按照 Bash 启动文件中描述的方式读取并执行启动文件。
- 默认情况下启用作业控制 (见作业控制)。当作业控制生效时,Bash 会忽略键盘生成的作业控制信号 SIGTTIN、SIGTTOU 和 SIGTSTP。
- Bash 会在打印主提示符
$PS1(见 Bash 变量)之前,将 PROMPT_COMMAND 数组变量中已设置元素的值作为命令执行。 - Bash 在读取命令的第一行之前会展开并显示 PS1,在读取多行命令的第二行及后续行之前会展开并显示 PS2。Bash 在读取命令后但在执行命令之前会展开并显示 PS0。有关提示字符串转义序列的完整列表,请参见"控制提示符"。
- Bash 使用 Readline(参见命令行编辑)从用户的终端读取命令。
- Bash 检查 ignoreeof 选项的值,以便在读取命令时在遇到标准输入的 EOF 时设置 -o,而不是立即退出(参见 Set 内建命令)。
- Bash 默认启用命令历史(参见 Bash 历史功能)和历史扩展(参见历史扩展)。当启用历史的 shell 退出时,Bash 会将命令历史保存到 $HISTFILE 指定的文件中。
- 别名扩展(参见别名)默认会执行。
- 如果没有任何陷阱,Bash 会忽略 SIGTERM(参见信号)。
- 如果没有任何陷阱,SIGINT 会被捕获并处理(参见信号)。SIGINT 会中断某些 shell 内建命令。
- 如果启用了 huponexit shell 选项(参见信号),交互式登录 shell 退出时会向所有作业发送 SIGHUP。
- -n 选项没有任何效果,无论是在调用时还是使用 'set -n' 时(参见 内置命令 set)。
- Bash 会定期检查邮件,这取决于 MAIL、MAILPATH 和 MAILCHECK 这几个 shell 变量的值(参见 Bash 变量)。
- 启用 'set -u' 后,shell 在展开引用未绑定的 shell 变量时不会退出(参见 内置命令 set)。
- 在
${var:?word}展开中,如果 var 未设置或为空导致展开错误,shell 也不会退出(参见 Shell 参数展开)。 - 由 shell 内置命令遇到的重定向错误不会导致 shell 退出。
- 在 POSIX 模式下,返回错误状态的特殊内置命令也不会导致 shell 退出(参见 Bash 和 POSIX)。
- 执行失败的 exec 不会导致 shell 退出(参见 Bourne Shell 内置命令)。
- 解析器语法错误不会导致 shell 退出。
- 如果启用了 cdspell shell 选项,shell 将尝试对 cd 内建命令的目录参数进行简单的拼写纠正(参见 The Shopt Builtin 中 shopt 内建命令的 cdspell 选项说明)。cdspell 选项仅在交互式 shell 中有效。
- shell 会检查 TMOUT 变量的值,如果在打印 $PS1 后指定的秒数内未读取到命令,则退出(参见 Bash 变量)。