試してみたところ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'
実行中のシェルは、適用した最初の引用符の層を削除します。 は-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 +++