Der Watch-Befehl mit Shell erkennt Dateinamen nicht

Der Watch-Befehl mit Shell erkennt Dateinamen nicht

Beim Versuch watch bash -c 'du -h /etc/passwd && df -h'wurde der Pfad zur Datei anscheinend vollständig ignoriert und stattdessen du -hdas aktuelle Arbeitsverzeichnis verwendet. Dasselbe Ergebnis wurde beobachtet, als ich ausführte watch bash -c 'stat /etc/passwd && df -h'und stateinen 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 watchan der Argumentaufteilung oder bashan der Argumentaufteilung?

Antwort1

watchfü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 logenthä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 +++

verwandte Informationen