Beim Versuch watch bash -c 'du -h /etc/passwd && df -h'
wurde der Pfad zur Datei anscheinend vollständig ignoriert und stattdessen du -h
das aktuelle Arbeitsverzeichnis verwendet. Dasselbe Ergebnis wurde beobachtet, als ich ausführte watch bash -c 'stat /etc/passwd && df -h'
und stat
einen Fehler zurückgab stat: missing operand
. Im Gegensatz dazu funktioniert die Verwendung von watch -e "command /path/to/file"
oder watch "command /path/to/file"
problemlos.
Warum funktioniert es watch bash -c 'du -h /etc/passwd && df -h'
dann nicht? Liegt es watch
an der Argumentaufteilung oder bash
an der Argumentaufteilung?
Antwort1
watch
führt Befehle mit Argumenten aus, indem sie an übergeben werden sh -c
. Sie führen also letztendlich Folgendes aus:
sh -c 'bash -c du -h /etc/passwd && df -h'
Die Shell, die Sie ausführen, entfernt die erste Ebene der von Ihnen angewendeten Anführungszeichen. Die -h
, werden dann als und an Bash /etc/passwd
übergeben , sodass sie effektiv ignoriert werden. Führen Sie etwas wie Folgendes aus:$0
$1
watch 'du -h /etc/passwd && df -h'
watch "bash -c 'du -h /etc/passwd && df -h'"
Zur Überprüfung verwenden Sie strace
:
strace -fe execve -o log watch bash -c 'du -h /etc/passwd && df -h'
Und log
enthält:
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 +++