По определению человека эта команда получает входные данные из файла.
$ command -r FILENAME
Предположим, что FILENAME
это файл, содержащий список имен файлов, как это было сгенерировано с помощью ls > FILENAME
.
Как я могу вместо этого кормить команду результатом ls
непосредственно? В моей голове что-то вроде этого должно быть возможно:
$ ls | command -r
Но это не так, вывод ls
не попадает в качестве аргумента. Выход:
Usage: command -r FILENAME
error: -r option requires an argument
Как я мог получить желаемый эффект?
Ответы:
Это зависит от команды. Некоторые команды, которые читают из файла, ожидают, что файл будет обычным файлом, размер которого известен заранее, и который можно прочитать из любой позиции и перезаписать. Это маловероятно, если содержимое файла представляет собой список имен файлов: тогда команда, вероятно, будет содержать канал, который будет просто последовательно читать от начала до конца. Существует несколько способов передачи данных через канал в команду, которая ожидает имя файла.
Многие команды обрабатываются
-
как специальное имя, означающее чтение из стандартного ввода, а не открытие файла. Это соглашение, а не обязательство.Многие варианты Unix предоставляют специальные файлы,
/dev
которые обозначают стандартные дескрипторы. Если/dev/stdin
существует, его открытие и чтение из него эквивалентно чтению из стандартного ввода; Точно так же,/dev/fd/0
если он существует.Если вашей оболочкой является ksh, bash или zsh, вы можете заставить оболочку заниматься выделением некоторого файлового дескриптора. Основным преимуществом этого метода является то, что он не привязан к стандартному вводу, поэтому вы можете использовать стандартный ввод для чего-то другого, и вы можете использовать его более одного раза.
Если команда ожидает, что имя будет иметь конкретную форму (как правило, конкретное расширение), вы можете попытаться обмануть его с помощью символической ссылки.
Или вы можете использовать именованный канал.
Обратите внимание, что создание списка файлов с
ls
проблемой является проблематичным, посколькуls
имеет тенденцию искажать имена файлов, когда они содержат непечатаемые символы.printf '%s\n' *
более надежен - он печатает каждый байт буквально в именах файлов. Имена файлов, содержащие символы новой строки, все равно будут вызывать проблемы, но это неизбежно, если команда ожидает список имен файлов, разделенных символами новой строки.источник
Так должно быть:
Изменить: для имен с пробелами:
источник
command
он считает, что в командной строке указаны все имена файлов, которые ему понадобятся. Некоторые версии xargs даютcommand
несколько имен файлов (мне кажется, 10) за раз. Похоже, GNU xargs дает все сразу.На самом деле, единственное надежное решение, которое мне известно, которое может обрабатывать все имена файлов, в том числе с новой строкой, это:
В этом случае единственным недопустимым символом в имени файла является нулевой символ, который в любом случае недопустим в именах файлов.
источник
Многие команды принимают
-
как «имя файла», что означает «использовать стандартный ввод», но это соглашение далеко не универсально. Прочитайте справочную страницу.источник
Это должно работать для вашей цели:
ls | command -r /dev/stdin
источник