Linux

理解 bash 命令行中的讀取、回顯和 grep 命令

  • December 27, 2020

誰能逐步解釋這個 bash 行中發生了什麼?我是新來的,試圖了解這段程式碼是如何工作的,尤其是來自echo

read char; echo -e "YES\nNO\n" | grep -i $char

行上的命令將字元串讀入變數char,可能是使用者互動的。

echo+grep管道嘗試確定輸入的字元串是否是肯定的。它通過匹配單詞YESNO輸入的字元串(以輸入的字元串作為模式)來做到這一點,不區分大小寫。如果使用者輸入單詞中存在的大寫或小寫字元或子字元串YES,則結果將是YES;如果他們輸入了字元串中存在的大寫或小寫字元或子字元串NO,則結果為NO. 輸入類似的內容maybe會導致輸出為空。

這種方法的缺點是,如果使用者輸入,例如,.兩者都匹配,YES並且將把點視為匹配任何字元的正則表達式。由於在對 的呼叫中未引用,因此如果使用者輸入諸如輸入之類的 shell 通配模式(範例取自忘記在 bash 中引用變數的安全隱患),它也有可能導致對機器的拒絕服務攻擊/POSIX 外殼)。您還可能通過輸入 eg 導致輸出與命令混淆(將在一行上單獨輸出每個非二進製文件的每個字元,前面是它所屬的文件的路徑名)。NO``grep``$char``grep``/*/*/*/*/../../../../*/*/*/*``-r -o -e . /

您顯示的程式碼是“奇怪和不尋常的”,因為它使用使用者輸入作為本質上的程式碼,即它使用使用者輸入作為模式,並針對此變數模式測試靜態*數據。*這與通常所做的相反,即從使用者那裡獲取輸入並針對靜態模式測試此可變數據。

更常見的是使用類似於以下的程式碼:

read -p 'Yes/[N]o: ' yesno
if [[ $yesno == [Yy]* ]]; then
  # code for affirmative
else
  # code for non-affirmative
fi

上面的程式碼從使用者那裡讀取一個字元串,並測試它是以 ay還是Y字元開頭。if如果確實如此,則將採用該語句的第一個分支,否則將預設採用該else分支。

您顯然也可以測試整個 word YES,或者[Yy][Ee][Ss]不區分大小寫的匹配,或者進行正確的輸入循環並進行驗證:

while true; do
   read -p 'Yes/No: ' yesno

   if [ "$yesno" = Yes ] || [ "$yesno" = No ]; then
       break
   fi

   echo 'Please enter "Yes" or "No"' >&2
done

# $yesno is either Yes or No here

(或類似的東西)。

請注意上面的兩個範常式式碼如何將使用者的輸入專門用作數據,而不是用作模式。

將您的原始命令最低限度地重寫為有點慣用的東西(但功能不同,並且可能不是萬無一失的)會將其變成

read yesno; printf '%s\n' "${yesno^^}" | grep -i -w -E 'yes|no'

這將返回大寫YESNO如果使用者鍵入yesor no。這在功能上是不同的,因為它要求使用者輸入的內容不僅僅是ea yes,例如。

引用自:https://unix.stackexchange.com/questions/572339