為什麼不看 bash -c ‘’echo $RANDOM’’ 列印任何東西?
我希望此命令每 2 秒在螢幕上列印一個隨機值,但它不會列印任何內容:
watch bash -c '"echo $RANDOM"'
但是,此命令確實每 2 秒列印一個隨機值:
watch bash -c '"echo \$RANDOM"'
顯然我必須轉義美元符號,但我想了解原因,因為在第一種情況下,watch 命令在頂部報告正在正確執行命令:
Every 2.0s: bash -c "echo $RANDOM"
在第二種情況下,它報告正在執行此命令,如預期的那樣:
Every 2.0s: bash -c "echo \$RANDOM"
好的,我明白了,必須轉義美元符號才能正確到達 bash 命令。但是,為什麼?watch 命令在執行命令之前對 $RANDOM 做了什麼以使其不輸出任何內容?
就像評論中提到的@steeldriver 一樣,預設情況
watch
下通過sh -c
. 不過,它似乎首先使用空格加入任何參數。和
watch bash -c '"echo $RANDOM"'
它獲取 args
bash
,-c
,"echo $RANDOM"
, 產生bash -c "echo $RANDOM"
, 並sh
使用兩個 args-c
和bash -c "echo $RANDOM"
.然後
sh
是雙引號內的變數並適當地擴展它。如果您sh
不支持 special$RANDOM
,則可能未設置整個變數,並且您在那裡得到一個空字元串。然後生成的命令是bash -c "echo "
,它啟動 Bash,告訴它只列印一個換行符。(如果你
sh
是 Bash 並且確實有$RANDOM
,那麼你可以只使用watch 'echo $RANDOM'
。)如果添加反斜杠,外殼 (
sh
) 會看到... "echo \$RANDOM"
,它不會擴展,而只是刪除反斜杠。內殼 (bash
) 看到echo $RANDOM
並擴展變數本身。如果您將外殼安排為 get... 'echo $RANDOM'
,則使用單引號也是如此。您可以看到中間外殼使用以下內容進行的擴展(它應該列印
out
):export foo=out; watch 'bash -c "foo=in; echo $foo"'
使用
watch -x
,它會跳過中間的 shell,這將按照您期望的方式工作,而無需引用地獄:watch -x bash -c 'echo $RANDOM'