Shell

為什麼 watch 會使 ls /tmp 列出 $HOME 的內容?

  • January 29, 2016

我正在嘗試查看/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作為單個參數傳遞給-cto sh,它按預期執行。如果沒有這個反引號,則命令在watch執行時會被分詞,而sh後者又會執行提供的sh,因此僅ls作為參數傳遞給-c,這意味著子子sh只會執行一個裸ls命令,並列出目前工作的內容目錄。

那麼,為什麼會出現並發症sh -c ...?為什麼不簡單地執行watch 'ls /tmp|wc -l'

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