J'essaie de regarder le nombre de fichiers dans mon /tmp/
répertoire. Pour cela, je pensais que cette commande fonctionnerait:
watch sh -c 'ls /tmp/|wc -l'
Mais cela semble fonctionner comme s'il ls
n'avait pas d'arguments. A savoir, je suis ~
dedans, et j'y reçois un certain nombre de fichiers au lieu de /tmp/
. J'ai trouvé une solution de contournement, qui semble fonctionner:
watch sh -c 'ls\ /tmp/|wc -l'
Mais pourquoi dois-je échapper à l'espace entre ls
et /tmp/
? Comment la commande est-elle transformée par watch
afin que la ls
sortie soit alimentée wc
, mais /tmp/
ne soit pas passée en argument ls
?
watch "sh -c 'ls /tmp | wc -l'"
l'exécution de cette commande devrait obtenir l'effet souhaité. Ce n'est pas la faute des montres, essayezsh -c ls /tmp
et vous obtiendrez votre répertoire personnel (mais je ne sais pas pourquoi ...)watch
correctement .La commande que vous passez àwatch
est à son tour alimenté parwatch
desh -c
, vous êtes en effet fairesh -c
deux fois./tmp
est un argument poursh
, dans ce cas, pas un argument pourls
.Réponses:
La différence peut être vue via
strace
:Dans le cas de la citation arrière,
ls /tmp
est passé en tant qu'argument unique au-c
tosh
, qui s'exécute comme prévu. Sans cette citation inverse, la commande est plutôt divisée en mots lors de l'watch
exécutionsh
qui à son tour exécute le fournish
, de sorte que seulls
est passé comme argument à-c
, ce qui signifie que le sous-sous-sh
programme exécutera uniquement unels
commande nue et répertorie le contenu du travail en cours annuaire.Alors, pourquoi la complication
sh -c ...
? Pourquoi ne pas simplement courirwatch 'ls /tmp|wc -l'
?la source
strace
.ls /tmp
est ... » et « Sans cette backquote , la commande est ... », et les utilisationsbq
etnobq
les noms de fichiers, lorsque tout en se référant à la barre oblique inverse dans votrels\ /tmp
commande.Il existe deux catégories principales de
watch
commandes (celles qui doivent exécuter des commandes périodiquement,watch
n'est pas une commande standard, il existe même des systèmes oùwatch
quelque chose de complètement différent comme espionner sur une autre ligne tty sur FreeBSD).Celui qui transmet déjà la concaténation de ses arguments avec des espaces à un shell (il fait en fait appel
sh -c <concatenation-of-arguments>
) et celui qui exécute simplement la commande spécifiée avec les arguments spécifiés sans invoquer de shell.Vous êtes dans la première situation, il vous suffit donc:
Quand vous faites:
votre
watch
fonctionne réellement:Et
sh -c ls /tmp/
exécute lels
script en ligne où$0
est/tmp/
(doncls
est exécuté sans arguments et répertorie le répertoire actuel).Certaines des
watch
implémentations de la première catégorie (comme celle de procps-ng sous Linux) acceptent une-x
option pour les faire se comporter comme celleswatch
de la deuxième catégorie. Donc avec ça, vous pouvez faire:la source