Используя данные, считанные с канала вместо этого, чем из файла в опциях команды

В то время как -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.

18
19.07.2011, 21:52
5 ответов

Это зависит от команды. Некоторые команды, которые читают из файла, ожидают, что файл является регулярным файлом, размер которого известен заранее, и который может быть считан из любого положения и перемотан. Это маловероятно, если содержание файла является списком имен файлов: затем команда, вероятно, будет довольна каналом, который она просто считает последовательно от начала до конца. Существует несколько способов подать данные через канал к команде, которая ожидает имя файла.

  • Много обработок команд - как специальное имя, означая читать из стандартного входа вместо того, чтобы открыть файл. Это - конвенция, не обязательство.

    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' * более надежно — это распечатает каждый байт буквально в именах файлов. Имена файлов, содержащие новые строки, все еще доставят неприятности, но это неизбежно, если команда ожидает список имен файлов, разделенных новыми строками.

32
27.01.2020, 19:45
  • 1
    +1 для перечисления всех возможностей. Замена процесса IMO является корректным ответом для этой ситуации. –  glenn jackman 20.07.2011, 01:11

Это должно быть:

ls | xargs -n 1 command -r

Править: для имен с пробелами:

ls | xargs -d '\n' -n 1 command -r
7
27.01.2020, 19:45
  • 1
    Это могло быть проблематично если command полагает, что это имеет все имена файлов, в которых будет требоваться на командной строке внезапно. Некоторые версии xargs дадут command несколько имен файлов (10, это кажется мне), за один раз. Похож на GNU xargs, дает все внезапно. –  Bruce Ediger 19.07.2011, 23:39

Много команд принимают - поскольку "имя файла", которое означает, "использует стандартный вход", но эта конвенция совсем не универсальна. Прочитайте страницу справочника.

1
27.01.2020, 19:45

Это должно работать на Вашу цель: ls | command -r /dev/stdin

1
27.01.2020, 19:45

На самом деле единственное надежное решение, которое я знаю этого, может обработать все имена файлов, включая тех, которые имеют новую строку в них:

find . -maxdepth 1 -print0 | xargs -n 1 -0 command -r

Единственное не допустимый символ в имени файла в этом случае является нулевым символом, который не позволяется в именах файлов так или иначе.

2
27.01.2020, 19:45

Теги

Похожие вопросы