Почему `cp` был разработан для автоматической перезаписи существующих файлов? [closed]

Встроенная поддержка ядра Linux для TCP keepalive аффектов все TCP-сокеты с поддержкой поддержки активности.

Поддержка активности TCP не включена по умолчанию: приложения должны явно запрашивать контроль активности активности для своих сокетов с помощью интерфейса setsockopt .

Вы можете проверить, включена ли поддержка активности для определенного сокета, используя команду netstat с параметром -o, --timers :

Здесь вы можете видеть, что один и тот же процесс может открывать разные сетевые сокеты в обоих режимах:

# netstat -anpo | grep 8999
tcp        0      0 10.10.171.44:48744         10.10.139.30:8999          ESTABLISHED 18232/java          keepalive (83.39/0/0)

# netstat -anpo | grep 8009
tcp        0      0 10.10.171.44:8009          10.10.171.42:40947         ESTABLISHED 18232/java          off (0.00/0/0)
30
24.10.2018, 11:34
6 ответов

Поведение по умолчанию при перезаписи cpуказано в POSIX.

  1. If source_file is of type regular file, the following steps shall be taken:

    3.a. The behavior is unspecified if dest_file exists and was written by a previous step. Otherwise, if dest_file exists, the following steps shall be taken:

    3.a.i. If the -i option is in effect, the cp utility shall write a prompt to the standard error and read a line from the standard input. If the response is not affirmative, cp shall do nothing more with source_file and go on to any remaining files.

    3.a.ii. A file descriptor for dest_file shall be obtained by performing actions equivalent to the open() function defined in the System Interfaces volume of POSIX.1-2017 called using dest_file as the path argument, and the bitwise-inclusive OR of O_WRONLY and O_TRUNC as the oflag argument.

    3.a.iii. If the attempt to obtain a file descriptor fails and the -f option is in effect, cp shall attempt to remove the file by performing actions equivalent to the unlink() function defined in the System Interfaces volume of POSIX.1-2017 called using dest_file as the path argument. If this attempt succeeds, cp shall continue with step 3b.

Когда была написана спецификация POSIX, уже существовало большое количество сценариев со встроенным -предположением о поведении перезаписи по умолчанию. Многие из этих сценариев были разработаны для работы без непосредственного присутствия пользователя, например. как задания cron или другие фоновые задачи. Изменение поведения сломало бы их. Просмотр и изменение их всех, чтобы добавить опцию принудительной перезаписи, где это необходимо, вероятно, считалось огромной задачей с минимальными преимуществами.

Кроме того, командная строка Unix всегда разрабатывалась таким образом, чтобы опытный пользователь мог работать эффективно, даже за счет сложного обучения новичка. Когда пользователь вводит команду, компьютер должен ожидать, что пользователь действительно имеет в виду ее, без каких-либо дополнительных -предположений; пользователь должен быть осторожен с потенциально деструктивными командами.

Когда была разработана первоначальная версия Unix, в системах было так мало памяти и памяти по сравнению с современными компьютерами, что перезапись предупреждений и подсказок, вероятно, считалась расточительной и ненужной роскошью.

Когда писался стандарт POSIX, прецедент был прочно установлен, и авторы стандарта хорошо осознавали преимущества отсутствия нарушения обратной совместимости .

Кроме того, как описывали другие, любой пользователь может добавить/включить эти функции для себя, используя псевдонимы оболочки или даже создав замену команды cpи изменив их $PATH, чтобы найти замену перед стандартной системной командой., и при желании получить подстраховку таким образом.

Но если вы сделаете это, вы обнаружите, что создаете опасность для себя. Если команда cpведет себя одним образом при интерактивном использовании и другим образом при вызове из сценария, вы можете не помнить о существовании разницы. В другой системе,вы можете оказаться небрежным, потому что привыкли к предупреждениям и подсказкам в вашей собственной системе.

Если поведение в сценариях по-прежнему будет соответствовать стандарту POSIX, вы, вероятно, привыкнете к подсказкам при интерактивном использовании, а затем напишите сценарий, который выполняет некоторое массовое копирование -, а затем обнаружите, что вы снова непреднамеренно перезаписаны. что-то.

Если вы также активируете подсказки в сценариях, что будет делать команда при запуске в контексте, где нет пользователя, например. фоновые процессы или задания cron? Будет ли сценарий зависать, прерываться или перезаписываться?

Зависание или прерывание означает, что задача, которая должна была быть выполнена автоматически, не будет выполнена. Отсутствие перезаписи может иногда также вызывать проблему :само по себе, например, это может привести к тому, что старые данные будут дважды обрабатываться другой системой вместо замены данными с датами от -до -.

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

55
27.01.2020, 19:38

cp происходит с самого начала Unix. Он существовал задолго до того, как был написан стандарт Posix. Действительно, :Posix только что формализовал существующее поведение cpв этом отношении.

Речь идет об Эпохе (1970 -01 -01 ), когда мужчины были настоящими мужчинами, женщины были настоящими женщинами и пушистыми зверюшками... (Я отвлекся ). В те дни добавление дополнительного кода делало программу больше. Тогда это было проблемой, потому что первым компьютером с Unix был PDP -7 (, который можно было обновить до 144 КБ ОЗУ! ). Так что вещи были маленькими, эффективными, без -функций безопасности.

Итак, в те дни вы должны были знать, что вы делаете, потому что у компьютера просто не было возможности помешать вам сделать что-то, о чем вы потом пожалеете.

(Есть хороший мультфильм Зевара; поищите «zevar cerveaux Assistance par ordinateur», чтобы найти эволюцию компьютера. Или попробуйте http://a54.idata.over-blog.com/2/07/74/62/dessins-et-bd/le-CAO-de-Zevar---reduc.jpg, пока он существует)

Для тех, кто действительно заинтересован. (Я видел некоторые предположения в комментариях. ):Первоначальный cpпервый Unix состоял примерно из двух страниц кода на ассемблере (C появился позже ). Соответствующая часть была:

sys open; name1: 0; 0   " Open the input file
spa
  jmp error         " File open error
lac o17         " Why load 15 (017) into AC?
sys creat; name2: 0     " Create the output file
spa
  jmp error         " File create error

(Итак, хардsys creat)

И пока мы на этом :Версия 2 Unix использовала (фрагмент кода)

mode = buf[2] & 037;
if((fnew = creat(argv[2],mode)) < 0){
    stat(argv[2], buf);

, который также является жестким creatбез тестов и гарантий. Обратите внимание, что код C -для V2 Unix из cpсостоит менее чем из 55 строк!

21
27.01.2020, 19:38

Is it "do one thing at one time"?

Этот комментарий звучит как вопрос об общем принципе проектирования. Часто вопросы об этом очень субъективны, и мы не можем написать правильный ответ. Имейте в виду, что в этом случае мы можем закрыть вопросы.

Иногда у нас есть объяснение первоначального выбора дизайна, потому что разработчики (с )написали о них. Но у меня нет такого хорошего ответа на этот вопрос.

Почему cpразработан таким образом?

Проблема в том, что Unix уже более 40 лет.

Если бы вы создавали новую систему сейчас, вы могли бы сделать другой выбор дизайна. Но изменение Unix нарушит существующие сценарии, как упоминалось в других ответах.

Почему был разработан дляcpавтоматической перезаписи существующих файлов?

Короткий ответ: «Я не знаю» :-).

Поймите, что cp— это только одна проблема. Я думаю, что ни одна из оригинальных командных программ не защищала от перезаписи или удаления файлов. Оболочка имеет аналогичную проблему при перенаправлении вывода :

.
$ cat first.html > second.html

Эта команда также автоматически перезаписывает second.html.

Мне интересно подумать, как можно переделать все эти программы. Это может потребовать дополнительной сложности.

Я думаю, что это часть объяснения :раннего Unix, подчеркивавшего простоту реализации .Более подробное объяснение этого см. в разделе «чем хуже, тем лучше» в конце этого ответа.

Вы можете изменить > second.html, чтобы он останавливался с ошибкой, если second.htmlуже существует. Однако, как мы уже упоминали, иногда пользователь действительно хочет заменить существующий файл. Например, он может создавать сложную команду, пытаясь несколько раз, пока не сделает то, что ему нужно.

При необходимости пользователь может сначала запустить rm second.html. Это может быть хорошим компромиссом! У него есть некоторые возможные недостатки.

  1. Пользователь должен дважды ввести имя файла.
  2. Люди также получают много проблем, используя rm. Так что я бы тоже хотел сделать rmболее безопасным. Но как? Если мы заставим rmпоказывать каждое имя файла и запрашивать подтверждение у пользователя, ему теперь придется писать три строки команд вместо одной. Кроме того, если ей приходится делать это слишком часто, она выработает привычку набирать "y" для подтверждения, не задумываясь. Так что это может быть очень раздражающим, и это может по-прежнему быть опасным.

В современной системе я рекомендую установить команду trashи по возможности использовать ее вместо rm. Внедрение хранилища Trash было отличной идеей, например. для одного -пользовательского графического ПК .

Я думаю, что также важно понимать ограничения оригинального оборудования Unix -ограниченного ОЗУ и дискового пространства, вывод на медленные принтеры , а также систему и программное обеспечение для разработки.

Обратите внимание, что в оригинальной Unix не было автодополнения табуляции для быстрого заполнения имени файла для команды rm. (Кроме того, исходная оболочка Bourne не имеет истории команд, например. например, когда вы используете клавишу со стрелкой вверх вbash).

При выводе на принтер вы должны использовать редактор на основе строки -, ed. Это сложнее освоить, чем визуальный текстовый редактор.Вы должны распечатать несколько текущих строк, решить, как вы хотите их изменить, и ввести команду редактирования.

Использование > second.htmlнемного похоже на использование команды в строковом -редакторе. Его эффект зависит от текущего состояния. (Если second.htmlуже существует, его содержимое будет удалено ). Если пользователь не уверен в текущем состоянии, ожидается, что он сначала запустит lsили ls second.html.

«Простая реализация» как принцип проектирования

Существует популярная интерпретация дизайна Unix, которая начинается:

The design must be simple, both in implementation and interface. It is more important for the implementation to be simple than the interface. Simplicity is the most important consideration in a design.

...

Gabriel argued that "Worse is better" produced more successful software than the MIT approach: As long as the initial program is basically good, it will take much less time and effort to implement initially and it will be easier to adapt to new situations. Porting software to new machines, for example, becomes far easier this way. Thus its use will spread rapidly, long before a [better] program has a chance to be developed and deployed (first-mover advantage).

https://en.wikipedia.org/wiki/Worse_is_better

9
27.01.2020, 19:38

Дизайн "cp" восходит к оригинальному дизайну Unix. На самом деле за дизайном Unix стояла последовательная философия, которая чуть меньше половины -в шутку называлась Хуже -значит -Лучше*.

Основная идея заключается в том, что сохранение простоты кода на самом деле является более важным аспектом дизайна, чем наличие идеального интерфейса или «правильных действий».

  • Simplicity -- the design must be simple, both in implementation and interface. It is more important for the implementation to be simple than the interface. Simplicity is the most important consideration in a design.

  • Correctness -- the design must be correct in all observable aspects. It is slightly better to be simple than correct.

  • Consistency -- the design must not be overly inconsistent. Consistency can be sacrificed for simplicity in some cases, but it is better to drop those parts of the design that deal with less common circumstances than to introduce either implementational complexity or inconsistency.

  • Completeness -- the design must cover as many important situations as is practical. All reasonably expected cases should be covered. Completeness can be sacrificed in favor of any other quality. In fact, completeness must be sacrificed whenever implementation simplicity is jeopardized. Consistency can be sacrificed to achieve completeness if simplicity is retained; especially worthless is consistency of interface.

(упор минный)

Учитывая, что это был 1970 год, вариант использования «Я хочу скопировать этот файл только , если он еще не существует» был бы довольно редким вариантом использования для кого-то, выполняющего копирование. Если это то, что вы хотели, вы вполне могли бы проверить перед копированием, и это можно даже написать в сценарии.

Что касается того, почему ОС с таким подходом к проектированию оказалась той, которая выиграла у всех других ОС, созданных в то время, у автора эссе также была теория на этот счет.

A further benefit of the worse-is-better philosophy is that the programmer is conditioned to sacrifice some safety, convenience, and hassle to get good performance and modest resource use. Programs written using the New Jersey approach will work well both in small machines and large ones, and the code will be portable because it is written on top of a virus.

It is important to remember that the initial virus has to be basically good. If so, the viral spread is assured as long as it is portable. Once the virus has spread, there will be pressure to improve it, possibly by increasing its functionality closer to 90%, but users have already been conditioned to accept worse than the right thing. Therefore, the worse-is-better software first will gain acceptance, second will condition its users to expect less, and third will be improved to a point that is almost the right thing.

*-или то, что автор, но никто другой, назвал «подходом Нью-Джерси» .

10
27.01.2020, 19:38

Основная причина в том, что GUI по определению является интерактивным, тогда как двоичный файл, подобный /bin/cp— это просто программа, которую можно вызывать из любого места, например, из вашего GUI; -). Могу поспорить, что даже сегодня подавляющее большинство вызовов /bin/cpбудет осуществляться не с реального терминала, когда пользователь вводит команду оболочки, а скорее с HTTP-сервера, почтовой системы или NAS. Встроенная -защита от ошибок пользователя имеет смысл в интерактивной среде; в меньшей степени в простом двоичном коде. Например, ваш графический интерфейс, скорее всего, вызовет /bin/cpв фоновом режиме для выполнения фактических операций, и ему придется иметь дело с вопросами безопасности на стандартном выходе, даже если он просто задал пользователю!

Обратите внимание, что с самого первого дня было почти тривиально написать безопасную обертку вокруг /bin/cp, если это необходимо. Философия *nix заключается в том, чтобы предоставить пользователям простые строительные блоки, :из которых /bin/cpявляется одним из них.

0
27.01.2020, 19:38

Поскольку эти команды также предназначены для использования в сценариях, которые могут выполняться без какого-либо контроля со стороны человека, а также потому, что существует множество случаев, когда вы действительно хотите перезаписать цель (, философия оболочек Linux такова. что человек знает, что делает)

Есть еще несколько гарантий:

  • GNU cpимеет -n| --no-clobberопция
  • если вы скопируете несколько файлов в один cpбудет жаловаться, что последний не является каталогом.
18
27.01.2020, 19:38

Теги

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