![shell 中的 watch 命令无法识别文件名](https://linux22.com/image/1203447/shell%20%E4%B8%AD%E7%9A%84%20watch%20%E5%91%BD%E4%BB%A4%E6%97%A0%E6%B3%95%E8%AF%86%E5%88%AB%E6%96%87%E4%BB%B6%E5%90%8D.png)
在尝试时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
参数分割的问题?
答案1
watch
通过将参数传递给来执行带有参数的命令sh -c
,因此最终运行的是:
sh -c 'bash -c du -h /etc/passwd && df -h'
您正在运行的 shell 会删除您应用的第一层引号。-h
,随后作为和/etc/passwd
传递给 bash,因此它们实际上被忽略了。 运行如下命令:$0
$1
watch 'du -h /etc/passwd && df -h'
watch "bash -c 'du -h /etc/passwd && df -h'"
为了验证,使用strace
:
strace -fe execve -o log watch bash -c 'du -h /etc/passwd && df -h'
并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 +++