Bash 如何解析多标志命令?

How Bash parse multi-flag commands?

我正在尝试创建一个过于简化的 bash 版本,我尝试将程序拆分为“词法分析器 + 扩展器、解析器、执行器”。
在词法分析器中,我存储我的数据(命令、标志、文件)并从中创建标记,我的过程只是简单地逐个循环遍历给定的输入字符并使用状态机来处理状态,状态是一个特殊字符,一个字母数字字符或 space.
现在,当我处于字母数字状态时,我正在执行命令,当我再次遇到字母数字状态或如果 input[i] == '-' 时,我知道下一个标志在哪里,现在问题出在多标志命令上。 例如:

$ ls -la | grep "*.c"

我成功获得命令ls, grep和标志-la, *.c。 然而,使用多标志命令,如.

$ sed -i "*.bak" "s/a/b/g" file1 file2

在我看来很难,我还想不通,我怎么知道特定命令的标志在哪里结束,所以我的问题是 bash 如何解析这些多标志命令?任何关于我的问题的建议,将不胜感激!

shell 不会尝试解析命令参数;这是公用事业的责任。可能的命令参数语法范围,无论是在使用中还是潜在有用的,都太大了,无法尝试。

在 Unix-like 系统上,shell 识别命令行中的各个参数,主要是通过空格拆分,但也考虑到引号的使用和各种其他转换,例如“全球扩张”。然后它生成这些参数的向量(“argv”)并将向量传递给 execve,后者将它们交给新创建的进程。

在 Windows 系统上,shell 甚至不这样做。它只是将 command-line 作为字符串交给 command-line 工具来完成所有工作。 (为了提供一点兼容性,有一个由应用程序初始化代码调用的中间层,它最终调用 main()。这做了一些基本的 argument-splitting,尽管它的引用算法相当多从 Unix shell.)

中简化而来

据我所知,没有 command-line shell 试图识别 command-line 标志。你也不应该。

对于一些课外阅读,这里是 shell 从 Posix 标准解析的描述:https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html。尝试实现所有远远超出给你的任务要求的东西,我当然不建议你这样做。但它可能仍然很有趣,如果您开始使用 shell.

,理解它会对您有很大帮助

或者,您可以尝试阅读 the Bash manual,这可能更容易理解。请注意,Bash 实现了对 Posix 标准的大量扩展。