shell 无法识别文件名的 watch 命令

Ser*_*nyy 2 command-line bash watch-command

在尝试watch bash -c 'du -h /etc/passwd && df -h'时,文件路径似乎被完全忽略,而是du -h通过当前工作目录运行。当我运行时观察到相同的结果watch bash -c 'stat /etc/passwd && df -h',并stat返回stat: missing operand错误。相比之下,使用watch -e "command /path/to/file"watch "command /path/to/file"工作没有问题。

为什么不watch bash -c 'du -h /etc/passwd && df -h'工作呢?是争论watch的问题还是bash争论的问题?

mur*_*uru 5

watch通过将参数传递给 来执行带有参数的命令sh -c,因此您最终运行的是:

sh -c 'bash -c du -h /etc/passwd && df -h'
Run Code Online (Sandbox Code Playgroud)

您正在运行的 shell 会删除您应用的第一层引号。的-h/etc/passwd然后它被传递$0$1打坏,所以他们有效地忽略。运行类似:

watch 'du -h /etc/passwd && df -h'
watch "bash -c 'du -h /etc/passwd && df -h'"
Run Code Online (Sandbox Code Playgroud)

要验证,请使用strace

strace -fe execve -o log watch bash -c 'du -h /etc/passwd && df -h'
Run Code Online (Sandbox Code Playgroud)

log包含:

17132 execve("/usr/bin/watch", ["watch", "bash", "-c", "du -h /etc/passwd && df -h"], [/* 40 vars */]) = 0
17134 execve("/bin/sh", ["sh", "-c", "bash -c du -h /etc/passwd && df "...], [/* 42 vars */]) = 0
17135 execve("/bin/bash", ["bash", "-c", "du", "-h", "/etc/passwd"], [/* 42 vars */]) = 0
17135 execve("/usr/bin/du", ["du"], [/* 42 vars */]) = 0
17135 +++ exited with 0 +++
Run Code Online (Sandbox Code Playgroud)