Игнорировать часть строки с помощью sed

Во-первых, почему это делается таким образом? Одна из причин историческая: именно так это было сделано в Unix First Edition .

Файлы берутся парами; первая открывается для чтения, вторая создается в 17 режиме. Затем первая копируется во вторую.

«Создан» относится к системному вызову creat (тот, в котором , как известно, отсутствует e ), который обрезает существующий файл по заданному имени, если он есть.

И здесь исходный код cp в Unix Second Edition (я не могу найти исходный код First Edition). Вы можете увидеть вызовы open для исходного файла и creat для второго файла; и, в качестве улучшения Первого издания, если второй файл является существующим каталогом, cp создает файл в этом каталоге.

Но, вы можете спросить, почему это было сделано именно так в то время? Ответ на вопрос «почему Unix изначально сделал это именно так?» Почти всегда проста. cp открывает свой источник для чтения и создает его место назначения - а системный вызов для создания файла перезаписывает существующий файл, открывая его для записи, потому что это позволяет вызывающему наложить содержимое файла заданным укажите, существует ли файл уже или нет.

Теперь о том, где это задокументировано: на странице руководства FreeBSD .

Для каждого файла назначения, который уже существует, его содержимое перезаписывается, если позволяют разрешения. Его режим, идентификатор пользователя и идентификатор группы не меняются, если не указана опция -p.

Эта формулировка присутствовала по крайней мере еще в 1990 году (когда BSD была 4.3BSD). Аналогичная формулировка содержится в Solaris 10 :

Если целевой_файл существует, cp перезаписывает его содержимое, но режим (и ACL, если применимо), владелец и группа, связанные с ним, не меняются.

Ваш случай даже описан в руководстве HP-UX 10 :

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

POSIX помещает его в стандартный формат. Цитата из Single UNIX v2 :

Если dest_file существует, предпринимаются следующие шаги: (…) файловый дескриптор для dest_file будет получен путем выполнения действий, эквивалентных функции open () спецификации XSH, вызываемой с использованием dest_file в качестве аргумента пути и побитовое включающее ИЛИ для O_WRONLY и O_TRUNC в качестве аргумента oflag.

На страницах руководства и спецификации, которые я процитировал, указано, что если передана опция -f и попытка открыть / создать целевой файл завершится неудачно (обычно из-за отсутствия разрешения на запись в файл) , cp пытается удалить цель и снова создать файл. Это нарушит жесткую ссылку в вашем сценарии.

Вы можете сообщить об ошибке в документации руководства GNU coreutils , поскольку оно не документирует такое поведение. Даже описание - preserve = links , которое в вашем сценарии приведет к удалению ссылки paul и созданию нового файла, не дает понять, что происходит без - preserve = ссылки . Описание типа -f подразумевает, что происходит без него, но не разъясняет это («При копировании без этой опции и существующий целевой файл не может быть открыт для записи, копирование не выполняется. Однако с --сила, …").

4
04.12.2017, 17:43
0 ответов

Теги

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