Я пытаюсь посмотреть количество файлов в моем /tmp/
каталоге. Для этого я думал, что эта команда будет работать:
watch sh -c 'ls /tmp/|wc -l'
Но, похоже, работает так, как будто ls
не имеет аргументов. А именно, я нахожусь ~
, и я получаю количество файлов там вместо /tmp/
. Я нашел обходной путь, который, кажется, работает:
watch sh -c 'ls\ /tmp/|wc -l'
Но зачем мне выходить из пространства между ls
и /tmp/
? Как команда преобразуется watch
таким образом, что ls
вывод передается wc
, но /tmp/
не передается в качестве аргумента ls
?
watch "sh -c 'ls /tmp | wc -l'"
выполнение этой команды должно получить желаемый эффект. Это не ошибка часов, попробуйте,sh -c ls /tmp
и вы получите свой домашний каталог (но я понятия не имею, почему ...)watch
неправильно. Команда, которую вы передаете,watch
в свою очередь подаетсяwatch
, чтобыsh -c
, таким образом вы фактически делаетеsh -c
дважды./tmp
аргументsh
, в этом случае не аргументls
.Ответы:
Разницу можно увидеть через
strace
:В случае обратной цитаты
ls /tmp
передается как один аргумент-c
tosh
, который выполняется, как и ожидалось. Без этой обратной кавычки, команда вместо слова раскол , когдаwatch
бежитsh
в свою очередь , запускает поставляетсяsh
, так что толькоls
передается в качестве аргумента-c
, а это означает , что суб-субsh
будет работать только голуюls
команду, и перечисляет содержимое текущей работы каталог.Итак, почему осложнение
sh -c ...
? Почему бы просто не бежатьwatch 'ls /tmp|wc -l'
?источник
strace
это сделать.ls /tmp
это ...» и «Без этой обратной кавычки , команда ...», и используетbq
иnobq
как имена файлов, когда все время ссылаясь на обратную косую черту в вашейls\ /tmp
команде.Есть две основные категории
watch
команд (из которых, которые должны периодически запускать команды,watch
это не стандартная команда, есть даже системы, в которыхwatch
есть что-то совершенно иное, например, отслеживание другой строки tty во FreeBSD).Тот, который уже передает конкатенацию своих аргументов с пробелами в оболочку (в действительности это вызывает
sh -c <concatenation-of-arguments>
), и тот, который просто запускает команду, указанную с указанными аргументами, без вызова оболочки.Вы находитесь в первой ситуации, поэтому вам просто нужно:
Когда вы делаете:
ваш на
watch
самом деле работает:И
sh -c ls /tmp/
выполняетls
встроенный скрипт, где$0
есть/tmp/
(такls
что запускается без аргументов и перечисляет текущий каталог).Некоторые из
watch
реализаций в первой категории (например, из procps-ng в Linux) принимают-x
опцию, чтобы заставить их вести себя так же, какwatch
во второй категории. Так что с там вы можете сделать:источник