我正在嘗試創建一個過于簡化的 bash 版本,我嘗試將程式拆分為“lexer expander、parser、executor”。
在詞法分析器中,我存盤我的資料(命令、標志、檔案)并從中創建標記,我的程序只是逐個字符回圈遍歷給定的輸入字符并使用狀態機來處理狀態,狀態要么是特殊字符,要么是字母數字字符或空格。
現在,當我處于字母數字狀態時,我處于命令狀態,當我再次遇到字母數字狀態或 if 時,我知道下一個標志在哪里的方式input[i] == '-',現在問題出在多標志命令上。例如:
$ ls -la | grep "*.c"
我成功地得到了命令ls, grep和標志-la, *.c。但是,使用多標志命令之類的。
$ sed -i "*.bak" "s/a/b/g" file1 file2
在我看來這很困難,我還不知道,我怎么知道特定命令的標志在哪里結束,所以我的問題是 bash 如何決議這些多標志命令?關于我的問題的任何建議,將不勝感激!
uj5u.com熱心網友回復:
shell 不會嘗試決議命令引數;這是實用程式的責任。可能的命令引數語法的范圍,無論是在使用中還是可能有用的,都太大了,無法嘗試。
在類 Unix 系統上,shell 從命令列識別單個引數,主要是通過在空格處拆分,但也考慮到引號的使用和各種其他轉換,例如“glob 擴展”。然后它生成這些引數的向量(“argv”)并將向量傳遞給execve,然后將它們傳遞給新創建的行程。
在 Windows 系統上,shell 甚至不這樣做。它只是將命令列作為字串傳遞,并將其留給命令列工具來完成所有操作。(為了提供一點兼容性,有一個由應用程式初始化代碼呼叫的中間層,它最終呼叫main(). 這會進行一些基本的引數拆分,盡管它的參考演算法與 Unix 使用的演算法相比有相當多的簡化貝殼。)
據我所知,沒有任何命令列 shell 會嘗試識別命令列標志。你也不應該。
對于一些課外閱讀,這里是來自 Posix 標準的 shell 決議的描述:https ://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html 。試圖實作遠遠超出此任務給您的要求的所有內容,我當然不建議您這樣做。但它可能仍然很有趣,如果你開始使用 shell,理解它會對你有很大幫助。
或者,您可以嘗試閱讀Bash 手冊,這可能更容易理解。請注意,Bash 實作了對 Posix 標準的許多擴展。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/475843.html
