Как /bin/cp обрабатывает блочные устройства?

Этот пост использует расширение скобок bash:

$ printf "%s\n" --exclude-dir={a,b,c}
--exclude-dir=a
--exclude-dir=b
--exclude-dir=c

Однако раскрытие фигурных скобок не применяется, если имеется только один элемент, а фигурные скобки оставлены как -:

$ printf "%s\n" --exclude-dir={a}
--exclude-dir={a}

Поскольку расширение фигурных скобок является функцией bash (и некоторых других оболочек ), но не grep, для grep это выглядит так, как будто вы сказали исключить каталог с именем {_book}.

1
17.12.2019, 09:31
1 ответ
  • Когда исходный файл является обычным файлом, а целевое блочное устройство (и когда без переключателя командной строки -i или получено определение от -i ), POSIX говорит [1], что назначение должно быть открытым ()с O _WRONLY|O _TRUNC, а содержимое источника записано. И POSIX говорит [2], что поведение блочных устройств (среди других специальных )открытых ()ed с O _TRUNC определяется реализацией -, которая, по моему опыту, обычно перезаписывает из начало и оставить остальную часть без изменений, если исходный код меньше. GNU cp дополнительно имеет переключатель командной строки --удалить -место назначения, который, если исходный файл является обычным, а целевое блочное устройство, сначала отсоединит ()место назначения, а затем создаст на его месте обычный файл.

  • Когда исходный файл является блочным устройством и с параметром командной строки -R, POSIX говорит, что место назначения должно быть создано с тем же типом файла, что и источник. Обычно это mknod ()с соответствующим мажорным :минорным.

  • Теперь сложная часть, когда исходный файл является блочным устройством и без -R, кажется, что POSIX пропустил это. Реализация FreeBSD [4] открывала ()место назначения и записывала содержимое. В противоположность этому, GNU one [3] по умолчанию использует mknod ()в качестве адресата или, если с помощью --скопировать содержимое -, открыть ()и записать содержимое.


[1] cp.1posix, POSIX.1 -Shell & Utilities 2017https://pubs.opengroup.org/onlinepubs/9699919799/utilities/cp.html

[2] open.3posix

[3] cp, GNU Coreutilshttps://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html

‘-R’ ‘-r’ ‘--recursive’ (...) Special files are copied by creating a destination file of the same type as the source; see the --copy-contents option.

Этот текст находится в документе формата "info", но не в формате "man".

[4] выпуск freebsd/12.1.0https://github.com/freebsd/freebsd/blob/release/12.1.0/bin/cp/cp.c#L461

        case S_IFBLK:
        case S_IFCHR:
            if (Rflag && !sflag) {
                if (copy_special(curr->fts_statp, !dne))
                    badcp = rval = 1;
            } else {
                if (copy_file(curr, dne))
                    badcp = rval = 1;
            }

int copy_special()и int copy_file()определены в bin/cp/utils.c. Один мкнод (), а другой открывает ()и записывает содержимое.


toybox (лицензированная bsd альтернатива вызову busybox multi -,поставляется с Android ), кажется, всегда записывает содержимое. Может быть, я сделаю больше исследований в этом позже.

6
27.01.2020, 23:15

Теги

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