В то время как -R
posix четко определенный, -r
не является портативным!
На Linux, в GNU и реализациях BusyBox cp
, -r
и -R
эквивалентны.
С другой стороны, поскольку можно читать в странице руководства POSIX cp
, -r
поведение определяется реализацией.
* If neither the -R nor -r options were specified, cp shall take actions based on the type and contents of the file referenced by the symbolic link, and not by the symbolic link itself. * If the -R option was specified: * If none of the options -H, -L, nor -P were specified, it is unspecified which of -H, -L, or -P will be used as a default. * If the -H option was specified, cp shall take actions based on the type and contents of the file referenced by any symbolic link specified as a source_file operand. * If the -L option was specified, cp shall take actions based on the type and contents of the file referenced by any symbolic link specified as a source_file operand or any symbolic links encoun- tered during traversal of a file hierarchy. * If the -P option was specified, cp shall copy any symbolic link specified as a source_file operand and any symbolic links encoun- tered during traversal of a file hierarchy, and shall not follow any symbolic links. * If the -r option was specified, the behavior is implementation- defined.
Это зависит от команды. Некоторые команды, которые читают из файла, ожидают, что файл является регулярным файлом, размер которого известен заранее, и который может быть считан из любого положения и перемотан. Это маловероятно, если содержание файла является списком имен файлов: затем команда, вероятно, будет довольна каналом, который она просто считает последовательно от начала до конца. Существует несколько способов подать данные через канал к команде, которая ожидает имя файла.
Много обработок команд -
как специальное имя, означая читать из стандартного входа вместо того, чтобы открыть файл. Это - конвенция, не обязательство.
ls | command -r -
Много вариантов Unix обеспечивают специальные файлы в /dev
это определяет стандартные дескрипторы. Если /dev/stdin
существует, открытие его и чтение из него эквивалентны чтению из стандартного входа; аналогично /dev/fd/0
если это существует.
ls | command -r /dev/stdin
ls | command -r /dev/fd/0
Если Ваша оболочка является ksh, ударом или zsh, можно заключить сделку об оболочке с бизнесом выделения некоторого дескриптора файла. Основное преимущество этого метода состоит в том, что он не связывается со стандартным входом, таким образом, можно использовать стандартный вход для чего-то еще, и можно использовать его несколько раз.
command -r <(ls)
Если команда ожидает, что имя будет иметь конкретную форму (обычно конкретное расширение), можно попытаться одурачить его с символьной ссылкой.
ln -s /dev/fd/0 list.foo
ls | command -r list.foo
Или можно использовать именованный канал.
mkfifo list.foo
ls >list.foo &
command -r list.foo
Обратите внимание что, генерировав список файлов с ls
проблематично потому что ls
имеет тенденцию искажать имена файлов, когда они содержат непечатные символы. printf '%s\n' *
более надежно — это распечатает каждый байт буквально в именах файлов. Имена файлов, содержащие новые строки, все еще доставят неприятности, но это неизбежно, если команда ожидает список имен файлов, разделенных новыми строками.
Это должно быть:
ls | xargs -n 1 command -r
Править: для имен с пробелами:
ls | xargs -d '\n' -n 1 command -r
command
полагает, что это имеет все имена файлов, в которых будет требоваться на командной строке внезапно. Некоторые версии xargs дадут command
несколько имен файлов (10, это кажется мне), за один раз. Похож на GNU xargs, дает все внезапно.
– Bruce Ediger
19.07.2011, 23:39
Много команд принимают -
поскольку "имя файла", которое означает, "использует стандартный вход", но эта конвенция совсем не универсальна. Прочитайте страницу справочника.
На самом деле единственное надежное решение, которое я знаю этого, может обработать все имена файлов, включая тех, которые имеют новую строку в них:
find . -maxdepth 1 -print0 | xargs -n 1 -0 command -r
Единственное не допустимый символ в имени файла в этом случае является нулевым символом, который не позволяется в именах файлов так или иначе.