6.3 交互式shell
* 什么是交互式shell? 什么决定了一个shel是交互式的。
* 是交互式shell么? 怎么判断一个shell是交互式的。
* 交互式shell行为 交互式shell有什么不同?
6.3.1 何为交互式shell?
交互式shell是启动时除了 -s 之外,没有非选项参数,不指定 -c 选项,并且输入和错误输出都连接到终端(由isatty(3)确定),或者以 -i 选项启动的shell。
交互式shell一般从用户终端读取和写出内容到用户终端。
当启动交互式shell时,-s 选项一般用于设置位置参数。
6.3.2 是交互式shell么?
为了在脚本中确定Bash是否运行在交互模式,要测试特殊参数 ‘-’ 的值。当shell是交互式的时候,它的值包含i。例如:
case "$-" in *i*) echo This shell is interactive ;; *) echo This shell is not interactive ;; esac
或者,启动脚本检查变量PS1,在非交互式脚本中,它不被设置,而在交互式脚本中被设置。例如:
if [ -z "$PS1" ]; then echo This shell is not interactive else echo This shell is interactive fi
6.3.3 交互式shell行为
当shell运行在交互模式下,它的行为在某些方面改变了。
1. 按照 Bash启动文件 章节中的描述,读取和执行启动文件。
2. 默认启用作业控制(见 作业控制 章节)。当作业控制有效时,Bash忽略键盘产生的作业控制信号:SIGTTIN, SIGTTOU, 和 SIGTSTP。
3. Bash在读取命令的第一行之前,扩展和显示 PS1 ,在读取命令的第二行及后续的行之前扩展和显示 PS2 。
4. Bash在打印提示符 $PS1(见 Bash变量)之前,把变量 PROMPT_COMMAND 的值,当作命令执行。
5. Readline(见 命令行编辑 章节)用来从用户终端读取命令。
6. Bash在读取命令时,当它从标准输入接收到EOF时,不是立即退出,而是检测 set -o 的选项 ignoreeof 的值。(见 set内建命令 章节)
7. 命令历史(见 Bash历史工具 章节)和历史扩展(见 历史交互 章节)是默认启用的。交互式shell在退出时,Bash将保存命令历史到文件名为 $HISTFILE 的文件中。
8. 默认执行别名扩展(见 别名 章节)。
9. 没有其他陷阱时,Bash忽略 SIGTERM (见 信号 章节)。
10. 没有其他陷阱时,捕获并处理 SIGINT 。SIGINT 会中断某些shell内建命令。
11. 交互式登录shell在退出时,如果启用了 huponexit 选项,则shell发送 SIGHUP 到所有作业。(见 信号 章节)
12. 忽略 -n 调用选项,而 ‘set -n‘ 没有效果(见 set内建命令 章节)。
13. Bash会定期检查邮件,依赖于MAIL, MAILPATH, 和 MAILCHECK 变量(见 Bash变量 章节)。
14. 在启用了 ‘set -u‘ 后,由于参照了未绑定的shell变量而发生的扩展错误,不会导致shell退出。(见 set内建命令 章节)
15. 在 ${var:?word} 中,由于 var 未设置或者值为空,而引起的扩展错误,不会导致shell退出。(见 shell参数表达式 章节)
16. shell内建命令引起的重定向错误,不会导致shell退出。
17. 运行在POSIX模式下,一个特定的内建命令返回错误状态,不会导致 shell退出。(见 POSIX 模式 章节)
18. exec执行失败,不会导致shell退出。(见 Bourne shell内建命令 章节)
19. 解析错误不会导致shell退出。
20. 默认启用 cd 内建命令的目录参数的简单拼写修正功能。(见 shopt 内建命令 章节中的shopt内建命令的cdspell选项的描述)
21. 打印 $PS1 之后,在指定秒数内,没有读到命令时,shell会检查 TMOUT 的值并退出。(见 shell变量 章节)