簡體   English   中英

檢查輸入是否是有效的Shell命令,Linux

[英]Checking if input is a valid shell command, Linux

我正在為任務開發一個簡單的外殼。 我讀取了用戶輸入的命令,將其標記為fork() ,然后在子進程中使用execvp()在后台執行該命令。

問題是我需要實現一個記錄有效命令的歷史記錄功能。 我知道檢查用戶輸入的字符串是否有效的唯一方法是檢查execvp()返回-1。 這是檢查無效命令的一種好方法,但是由於對execvp()的調用發生在子進程中,並且我用於歷史記錄的數據結構被復制到fork()上的fork()而不是共享,所以我可以請使用子對象中execvp()的結果來更新歷史記錄(由於歷史記錄結構是副本,因此我所做的任何更改都不會反映在父結構的副本中)。

有什么方法可以檢查execvp() 是否會返回-1而不實際調用它(即在fork之前或之后)? 如果我能找到一種方法,可以在父進程中驗證execvp()是否會成功,並使用該信息正確更新我的歷史記錄數據結構。

您要的是一個系統調用,該調用可讓您實現經典的先檢查后競賽條件。

在該錯誤中,程序將驗證是否有可能執行某項操作,然后執行該操作,從而使檢查之后的某些外部事件(使該操作非法)的可能性得以保留。

因此,即使程序檢查了是否可行,操作也失敗了。 這通常會導致混亂。

您應該避免使用這種反模式,而系統API應該通過不誘使您陷入麻煩的系統調用來幫助您。 在這種情況下,系統會做正確的事; 沒有這樣的API。

父進程最終必須檢索子進程的退出狀態。 那是您需要更新(或不需要)歷史記錄的時刻。 如果失敗的execvp導致子進程以失敗狀態代碼退出(),則父進程會注意到該失敗,並且可以通過不向歷史記錄添加命令行來做出反應。


經過一番思考后添加了一些注釋:

  1. 要檢索子進程的狀態碼,父進程將調用waitwaitpid 對於同步執行,父級可能會立即執行; 對於異步執行,父級在收到SIGCHLD信號時會這樣做。 但是家長必須這樣做,以避免僵屍進程。

  2. 在異步執行的情況下,無法使用此策略來避免將無效命令放入歷史記錄,因為異步命令在啟動時必須記錄在歷史記錄中。 出於類似的原因,即使命令無效,Posix Shell也將命令的異步執行視為成功。

  3. 盡管此練習無疑具有教學法的價值(正如我希望這個答案所證明的那樣),但實際上這是做殼歷史的一種可怕方法。 盡管Shell用戶偶爾會使用歷史記錄來檢索和重新執行成功的命令,但是歷史記錄功能對於檢索和編輯不成功的命令更為有用。 無法從歷史記錄功能進行更正,這非常煩人。 (許多Android應用程序都在搜索歷史記錄中確實表現出這種令人討厭的缺陷:進行搜索后,您會得到不想要的結果,您可以檢索不正確的搜索並重新運行它,但不能修改它。 Android系統。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM