讓我們假設以下腳本:
echo "if test 1 -eq $1 ; then echo ls;fi" | tee /tmp/toto
cat /tmp/toto
$(cat /tmp/toto)
使用此命令運行它時:
./non_secure_script 1
我收到以下錯誤:
if: command not found
但是,以下命令運行成功:
$(if test 1 -eq 1; then echo ls;fi)
為什么會這樣?
uj5u.com熱心網友回復:
由于傳統/標準的大多數決議(即,不* CSH,RC,等)殼輸入,在像特定識別保留字if和化合物命令等if ...; then ...; fi完成之前一樣擴張$( command )。請參閱POSIX 定義的序列,特別是頁面后面的第 2 步和第 3 步以及第 2.2-2.4 節,而不是頁面后面的第 4 步和第 2.5-2.6 節,而不是鏈接的“wordexp”(!!!)。
如果你這樣做了$(/tmp/toto)or $(. /tmp/toto)—— 或者$(source /tmp/toto)在將它作為同義詞的 shell 上—— 它會在子 shell 中執行if-construct 并只將字串ls(或什么都不回傳)回傳到主 shell 。由于主殼決議了這是一個簡單的命令(見上面的鏈接頁面上的第2.9.1節)之前擴大,并且ls是一個有效的簡單的命令,它被成功執行。因為分詞和路徑名擴展(通常稱為通配符)在 2.6 節中作為擴展的最后一步完成(除非禁用),回傳具有多個空格分隔的單詞 like 的字串ls -la會起作用,除非它們包含像?or這樣的通配符*,但參考 likels -la 'file with spaces'是行不通的。
您的第二個案例$(if...fi)出于同樣的原因;它在子 shell 中執行 if-construct 并回傳僅ls在主 shell 中執行,這是一個有效的簡單命令。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/383725.html
上一篇:在帶路徑的檔案名前添加test_
