При попытке 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
передаются как $0
и $1
в bash, поэтому они фактически игнорируются. Запустите что-то вроде:
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 +++