Please enable Javascript to view the contents

Linux基础-命令行处理: Command-line Processing

 ·  ☕ 6 分钟

相关博客

[Blog-1]:Linux经验: 终端命令行快捷键-Readline

了解命令行处理过程非常重要。查看命令的处理过程,可以让你知道命令是如何失败的。 它可以帮助你确定失败的原因,以及如何修复,使其正常运行。

1.简介

什么是命令行处理(Command-line Processing)?

命令行处理:指处理器解析命令行输入指令的过程。

处理器对下达的每一条指令都要经过七个步骤。

7步处理

  1. Reads Command: 读取命令;
    从文件、字符串中读取command。文件是指脚本文件,主要由一组单独的命令或字符串组成。 命令字符串是在终端键入的字符串或脚本的单行。

  2. Tokenization: 代码化,shell会将输入内容分解为词块(Token):单词words和运算符operators;
    Token由元字符进行分隔。元字符包括|&;()<>空格制表符换行符。不包含元字符引号的Token是 “word”。 不含引号且至少包含一个元字符的Token是 “操作符”。操作符有两种:控制和重定向。控制操作符:newline|||&&&;;;;&;;&|&()重定向操作符:<><<>><&>|<←<>>&
    操作符只有在不加引号的时候有意义。

  3. Command Identification:

  4. Command Expansion:

  5. Quote Removal

  6. Redirections

  7. Command Execution

如何确定?

要在启动脚本中确定 Bash 是否以交互方式运行,可以通过以下两种方式:

  1. 判断运行参数-的值中,是否包含i。例如, 执行echo $-命令,返回值为himBHs(参数详细说明,见), 其中的i说明shell以交互式运行。

  2. 通过环境变量PS1判断, 此环境变量存在,则为交互式shell。

2.交互式Shell行为

当 Bash 以交互式模式运行时,它会在以下几个方面改变其行为:

  1. Bash启动文件
    启动时根据Bash启动文件的规则,读取文件并执行;
  2. 作业控制信号处理
    默认启用作业控制,此时,Bash会忽略键盘的作业控制信号SIGTTINSIGTTOUSIGTSTP;
  3. 提示符展开
    Bash在读取命令的第一行之前,展开并显示$PS1
    在读取多行命令的第二行及后续各行之前,展开并显示$PS2
    在读取命令后、执行命令前,会展开并显示$PS0
    参见【注2】: “控制提示”(提示字符串转义序列的完整列表)
  4. PROMPT_COMMAND执行
    Bash会在打印 主提示符 $PS1之前,将 数组变量 PROMPT_COMMAND中的元素作为命令来执行。
    参见 “Bash变量”(由Bash设置、使用,其他 shell 通常不特别处理的变量)
  5. Readline
    用于从用户终端读取命令。参见 【注4】:“命令行编辑Readline”
  6. ignoreeof选项
    检查set -o的 ignoreeof 选项的值。当ignoreeof被设置时,标准输入端收到EOF(非自定义终止符,而是快捷键Ctrl+D发出的终止信号)时, 不再立即退出
    (参见【注5】:“Set命令”(Bash的选项设置))。
  7. 历史命令和展开
    默认开启命令历史记录(参见【注6】:“History”(Bash 历史记录功能))、历史记录扩展(参见【注7】:“History Expansion”(Bash 历史命令展开机制))。此时,shell退出时,Bash会将历史命令保存到名为$HISTFILE的文件中。
  8. Alias别名展开
    默认执行别名展开。
  9. 信号处理
    没有任何traps的情况下,Bash忽略SIGTERM ,捕获并处理SIGINT信号。参见 【注8】:“Signals”(Bash对信号的处理)
  10. 如果设置了huponexit选项,交互式Login-Shell会在退出时,向所有作业发生SIGHUP 信号。
  11. 选项-n被忽略
    交互式Shell下,选项-n会被忽略,执行set -n不会有任何效果(-n:读取命令但不执行,用于检查脚本语法错误)。
  12. 邮件检查
    根据环境变量MAILMAILPATHMAILCHECK定期检查邮件。
  13. 以下报错会导致非交互模式shell退出,但交互式shell不会退出:
    • 未定义变量的展开错误

      -u(nounset):脚本引用未定义变量时,立即退出shell。用于避免因使用了未初始化变量而导致的错误。

      set -u在交互式shell中的行为与非交互式shell中不同,引用未定义变量时不在直接退出,而是回显报错信息

    • ${var:?word}的展开错误
      ${var:?word}展开中,变量未设置或为空时的展开错误不会导致 shell 退出。参见 【注9】:“Parameter Expansion”(Bash的参数展开)

    • 重定向错误
      由 shell 内置命令遇到的重定向错误不会导致 shell 退出。

    • POSIX模式下的特殊内置命令返回错误
      在 POSIX 模式下,特殊内置命令返回错误状态不会导致 shell 退出。

    • exec失败
      exec 失败不会导致 shell 退出。

    • 解析器语法错误
      解析器语法错误不会导致 shell 退出。

  14. cdspell选项。如果启用了 cdspell shell 选项,shell 会尝试对 cd 内置命令的目录参数进行简单的拼写校正。
  15. TMOUT变量。检查 TMOUT 变量的值,并在打印 $PS1 后指定的秒数内未读取到命令时退出。

3.总结

Bash 在交互式模式下的行为变化,包括对信号的处理、提示符的展开、命令历史的使用、别名的展开等,这些特性使得 Bash 在交互式环境中更加灵活和用户友好。

4.参考

【注1】:linux-Interactive Shell(交互式Shell行为说明)

【注2】:“控制提示”(提示字符串转义序列的完整列表)

【注3】:“Bash变量”(由Bash设置、使用,其他 shell 通常不特别处理的变量)

【注4】:“命令行编辑Readline”

【注5】:“Set命令”(Bash的选项设置)

【注6】:“History”(Bash 历史记录功能)

【注7】:“History Expansion”(Bash 历史命令展开机制)

【注8】:“Signals”(Bash对信号的处理)

【注9】:“Parameter Expansion”(Bash的参数展开)

分享

Hex
作者
Hex
CloudNative Developer

目录