Я проверил cp
с помощью следующих команд:
$ ls
first.html second.html third.html
$ cat first.html
first
$ cat second.html
second
$ cat third.html
third
Затем я копирую first.html
в second.html
:
$ cp first.html second.html
$ cat second.html
first
Файл second.html
молча перезаписывается без ошибок. Однако, если я сделаю это в графическом интерфейсе рабочего стола, перетащив файл с тем же именем, он будет добавлен first1.html
автоматически. Это позволяет избежать случайной перезаписи существующего файла.
Почему не cp
следует этому шаблону вместо того, чтобы перезаписывать файлы без вывода сообщений?
cp
дляcp -i
или подобное , потому что вы будете привыкать к тому , подстраховка, что делает системы , в которых он не доступен (большинство из них) , что гораздо более рискованными. Лучше учить себя регулярноcp -i
и т. Д., Если это то, что вы предпочитаете.Ответы:
Поведение перезаписи по умолчанию
cp
указано в POSIX.Когда была написана спецификация POSIX, уже существовало большое количество сценариев со встроенным допущением для поведения перезаписи по умолчанию. Многие из этих сценариев были разработаны для запуска без непосредственного участия пользователя, например, в качестве заданий cron или других фоновых задач. Изменение поведения сломало бы их. Просмотр и изменение их всех для добавления возможности принудительной перезаписи в любом месте, вероятно, считалось огромной задачей с минимальными преимуществами.
Кроме того, командная строка Unix всегда была разработана для того, чтобы опытный пользователь мог эффективно работать, даже за счет сложной кривой обучения для начинающего. Когда пользователь вводит команду, компьютер должен ожидать, что пользователь действительно это подразумевает, без каких-либо догадок; Пользователь обязан быть осторожным с потенциально разрушительными командами.
Когда была разработана оригинальная Unix, тогда системы имели настолько мало памяти и запоминающего устройства по сравнению с современными компьютерами, что перезаписывали предупреждения и подсказки, вероятно, рассматривались как расточительная и ненужная роскошь.
Когда был написан стандарт POSIX, прецедент был твердо установлен, и разработчики стандарта хорошо знали о достоинствах не нарушая обратную совместимость .
Кроме того, как уже описывали другие, любой пользователь может добавить / включить эти функции для себя, используя псевдонимы оболочки или даже создав
cp
команду замены и изменив их,$PATH
чтобы найти замену перед стандартной системной командой, и таким образом получить защитную сеть, если желательно.Но если вы сделаете это, вы обнаружите, что создаете опасность для себя. Если
cp
команда ведет себя одинаково при интерактивном использовании, а другая - при вызове из сценария, вы можете не помнить, что разница существует. В другой системе вы можете оказаться небрежным, потому что вы привыкли к предупреждениям и подсказкам в вашей собственной системе.Если поведение в сценариях будет по-прежнему соответствовать стандарту POSIX, вы, вероятно, привыкнете к подсказкам в интерактивном режиме, а затем напишите сценарий, который выполняет массовое копирование, а затем обнаружите, что вы снова случайно что-то перезаписали.
Если вы также навязываете запросы в сценариях, что будет делать команда, когда она запускается в контексте, в котором нет пользователя, например, фоновых процессов или заданий cron? Будет ли скрипт зависать, прерываться или перезаписывать?
Зависание или прерывание означает, что задача, которая должна была быть выполнена автоматически, не будет выполнена. Отсутствие перезаписи может иногда также вызывать проблему само по себе: например, это может привести к тому, что старые данные будут дважды обрабатываться другой системой вместо их замены на обновленные данные.
Большая часть возможностей командной строки заключается в том, что как только вы узнаете, как что-то делать в командной строке, вы также будете неявно знать, как сделать это автоматически с помощью сценариев . Но это верно только в том случае, если команды, которые вы используете в интерактивном режиме, также работают точно так же, когда вызываются в контексте скрипта. Любые существенные различия в поведении между интерактивным использованием и использованием сценариев создадут своего рода когнитивный диссонанс, который раздражает опытного пользователя.
источник
rm -rf
так эффективен, даже если вы на самом деле не хотели запускать его в своем домашнем каталоге ...cp
происходит от начала Unix. Это было задолго до того, как был написан стандарт Posix. Действительно: Posix только что формализовал существующее поведениеcp
в этом отношении.Мы говорим об Эпохе (1970-01-01), когда мужчины были настоящими мужчинами, женщины были настоящими женщинами и пушистыми маленькими существами ... (Я отвлекся). В те дни добавление дополнительного кода делало программу больше. Тогда это было проблемой, потому что первым компьютером, на котором работал Unix, был PDP-7 (с возможностью обновления до 144 КБ ОЗУ!). Так что все было маленьким, эффективным, без функций безопасности.
Итак, в те дни вы должны были знать, что вы делаете, потому что у компьютера просто не было возможности помешать вам сделать то, о чем вы потом сожалели.
(Есть замечательный мультфильм Зевара; найдите «zevar cerveaux assiste par ordinateur», чтобы найти эволюцию компьютера. Или попробуйте http://perinet.blogspirit.com/archive/2012/02/12/zevar-et- cointe.html пока он существует)
Для тех, кто действительно заинтересован (я видел некоторые предположения в комментариях): оригинал
cp
первого Unix был около двух страниц кода на ассемблере (C появился позже). Соответствующая часть была:(Итак, тяжело
sys creat
)И пока мы работаем над этим: используется версия 2 Unix (фрагмент кода)
что также трудно
creat
без тестов и гарантий. Обратите внимание, что C-код для V2 Unixcp
составляет менее 55 строк!источник
cp
просто редактировалиopen
пункт назначенияO_CREAT | O_TRUNC
и выполняли циклread
/write
; Конечно, у moderncp
есть так много ручек, что он в основном должен пытатьсяstat
добраться до места назначения заранее, и может легко сначала проверить существование (и делает это сcp -i
/cp -n
), но если ожидания были установлены с помощью оригинальныхcp
инструментов, меняющих это поведение, изменяющих это поведение сломал бы существующие сценарии без необходимости. Это не то, что современные оболочки сalias
просто не могут сделатьcp -i
по умолчанию для интерактивного использования.creat
это эквивалентноopen
+O_CREAT | O_TRUNC
), но отсутствиеO_EXCL
действительно объясняет, почему было бы не так легко обрабатывать существующие файлы; попытка сделать это была бы по сути своей редкостью (вам, в основном, нужноopen
/stat
проверить существование, затем использоватьcreat
, но на больших общих системах всегда возможно, когда вы дойдетеcreat
, кто-то другой сделал файл, и теперь вы взорваны это все равно). Можно просто перезаписать безоговорочно.Потому что эти команды также предназначены для использования в сценариях, возможно, выполняющихся без какого-либо человеческого контроля, а также потому, что существует множество случаев, когда вы действительно хотите перезаписать цель (философия оболочек Linux заключается в том, что человек знает, что она делает)
Есть еще несколько гарантий:
cp
имеет-n
|--no-clobber
вариантcp
то пожалуетесь, что последний не является каталогом.источник
Этот комментарий звучит как вопрос об общем принципе дизайна. Часто вопросы по этому поводу очень субъективны, и мы не можем дать правильный ответ. Имейте в виду, что в этом случае мы можем закрыть вопросы.
Иногда у нас есть объяснение первоначального выбора дизайна, потому что разработчики написали о них. Но у меня нет такого хорошего ответа на этот вопрос.
Почему
cp
так устроено?Проблема в том, что Unix старше 40 лет.
Если бы вы создавали новую систему сейчас, вы могли бы сделать другой выбор дизайна. Но изменение Unix сломало бы существующие сценарии, как упомянуто в других ответах.
Почему был
cp
разработан, чтобы молча перезаписать существующие файлы?Краткий ответ: «Я не знаю» :-).
Поймите, что
cp
это только одна проблема. Я думаю, что ни одна из оригинальных командных программ не защищена от перезаписи или удаления файлов. Оболочка имеет аналогичную проблему при перенаправлении вывода:Эта команда также молча перезаписывает
second.html
.Мне интересно подумать, как все эти программы могут быть переработаны. Это может потребовать дополнительной сложности.
Я думаю, что это часть объяснения: ранний Unix подчеркивал простые реализации . Более подробное объяснение этого см. В разделе «Чем хуже, тем лучше», ссылка на который приведена в конце этого ответа.
Вы можете изменить
> second.html
его, чтобы он остановился с ошибкой, если онаsecond.html
уже существует. Однако , как мы уже упоминали, иногда пользователь делает хочет заменить существующий файл. Например, она может создавать сложную команду, пытаясь несколько раз, пока она не сделает то, что она хочет.Пользователь может запустить
rm second.html
первым, если ему нужно. Это может быть хорошим компромиссом! У него есть некоторые возможные недостатки.rm
. Поэтому я бы тоже хотел сделать егоrm
более безопасным. Но как? Если мыrm
показываем каждое имя файла и просим пользователя подтвердить, теперь она должна написать три строки команд вместо одной. Кроме того, если ей придется делать это слишком часто, она приобретет привычку и наберет «у», чтобы подтвердить, не задумываясь. Так что это может быть очень раздражающим и все же опасным.В современной системе я рекомендую установить
trash
команду и использовать ееrm
там, где это возможно. Внедрение Trash Storage было отличной идеей, например, для однопользовательского графического ПК .Я думаю, что также важно понимать ограничения оригинального оборудования Unix - ограниченное ОЗУ и дисковое пространство, вывод, отображаемый на медленных принтерах, а также на систему и программное обеспечение для разработки.
Обратите внимание, что в оригинальном Unix не было завершения табуляции , чтобы быстро заполнить имя файла для
rm
команды. (Кроме того, оригинальная оболочка Bourne не имеет истории команд, например, когда вы используете клавишу со стрелкой вверхbash
).При выводе на принтер вы бы использовали линейный редактор
ed
. Это сложнее освоить, чем визуальный текстовый редактор. Вы должны напечатать некоторые текущие строки, решить, как вы хотите их изменить, и ввести команду редактирования.Использование
> second.html
немного похоже на использование команды в редакторе строк. Эффект, который он оказывает, зависит от текущего состояния. (Если онsecond.html
уже существует, его содержимое будет удалено). Если пользователь не уверен в текущем состоянии, он должен запускатьсяls
илиls second.html
первым.«Простая реализация» как принцип проектирования
Существует популярная интерпретация Unix-дизайна, которая начинается с:
источник
cp
«проблему»? Наличие интерактивного запроса разрешения или неудачи может быть такой же большой «проблемой», как эта.cat first.html second.html > first.html
даст результат,first.html
будучи перезаписанным только с содержимымsecond.html
. Оригинальное содержание теряется на все времена.Дизайн "cp" восходит к оригинальному дизайну Unix. На самом деле, за дизайном Unix стояла последовательная философия, которая была чуть менее шутливо названа « Хуже-лучше» * .
Основная идея заключается в том, что упрощение кода на самом деле является более важным соображением дизайна, чем идеальный интерфейс или «правильная работа».
( акцент мой )
Помня, что это был 1970 год, вариант использования «Я хочу скопировать этот файл, только если он еще не существует» был бы довольно редким случаем для кого-то, кто выполняет копирование. Если это то, что вы хотели, вы вполне могли бы проверить перед копированием, и это можно даже записать в сценарии.
Что касается того, почему ОС с таким подходом к проектированию оказалась той, которая одержала победу над всеми другими ОС, создаваемыми в то время, у автора эссе также была теория для этого.
* - или то, что автор, но никто другой, назвал «подход Нью-Джерси» .
источник
creat()
противopen()
.open()
Не может создать файл , если он не существует. Он принимает только 0/1/2 для чтения / записи / другое. Это не займетO_CREAT
, и нетO_EXCL
).Основная причина в том, что графический интерфейс по определению является интерактивным, в то время как двоичный код
/bin/cp
- это просто программа, которую можно вызывать из любого места, например из вашего графического интерфейса ;-). Могу поспорить, что даже сегодня подавляющее большинство звонков/bin/cp
будет поступать не с реального терминала, где пользователь вводит команду оболочки, а с HTTP-сервера, почтовой системы или NAS. Встроенная защита от ошибок пользователя имеет смысл в интерактивной среде; меньше так в простом бинарном файле. Например, ваш GUI, скорее всего, будет вызывать/bin/cp
в фоновом режиме для выполнения реальных операций, и ему придется иметь дело с вопросами безопасности на стандартном out, даже если он только что спросил пользователя!Обратите внимание, что с первого дня было почти тривиально написать безопасную оболочку,
/bin/cp
если это необходимо. Философия * nix заключается в предоставлении пользователям простых строительных блоков: один из них/bin/cp
.источник