Shell為什麼
為什麼 watch
會使 ls /tmp
列出 $HOME 的內容?
我正在嘗試查看
/tmp/
目錄中的文件數。為此,我認為這個命令會起作用:watch sh -c 'ls /tmp/|wc -l'
但它似乎
ls
沒有任何論據。即,我在 中~
,並且我在那裡獲得文件數量而不是/tmp/
. 我找到了一種解決方法,它似乎有效:watch sh -c 'ls\ /tmp/|wc -l'
但是為什麼我需要逃避和之間的
ls
空間/tmp/
?命令如何轉換,watch
以便將ls
輸出提供給wc
,但/tmp/
不作為參數傳遞給ls
?
可以通過以下方式看到差異
strace
:$ strace -ff -o bq watch sh -c 'ls\ /tmp/|wc -l' ^C $ strace -ff -o nobq watch sh -c 'ls /tmp/|wc -l' ^C $ grep exec bq* | grep sh bq.29218:execve("/usr/bin/watch", ["watch", "sh", "-c", "ls\\ /tmp/|wc -l"], [/* 54 vars */]) = 0 bq.29219:execve("/bin/sh", ["sh", "-c", "sh -c ls\\ /tmp/|wc -l"], [/* 56 vars */]) = 0 bq.29220:execve("/bin/sh", ["sh", "-c", "ls /tmp/"], [/* 56 vars */]) = 0 $ grep exec nobq* | grep sh nobq.29227:execve("/usr/bin/watch", ["watch", "sh", "-c", "ls /tmp/|wc -l"], [/* 54 vars */]) = 0 nobq.29228:execve("/bin/sh", ["sh", "-c", "sh -c ls /tmp/|wc -l"], [/* 56 vars */]) = 0 nobq.29229:execve("/bin/sh", ["sh", "-c", "ls", "/tmp/"], [/* 56 vars */]) = 0
在反引號的情況下,
ls /tmp
作為單個參數傳遞給-c
tosh
,它按預期執行。如果沒有這個反引號,則命令在watch
執行時會被分詞,而sh
後者又會執行提供的sh
,因此僅ls
作為參數傳遞給-c
,這意味著子子sh
只會執行一個裸ls
命令,並列出目前工作的內容目錄。那麼,為什麼會出現並發症
sh -c ...
?為什麼不簡單地執行watch 'ls /tmp|wc -l'
?