У меня вопрос: почему -r
при создании копии каталога необходимо использовать флаг (рекурсивный)? Т.е. зачем это делать:
$ cp -r dir1 copyDir1
Когда бы я не хотел такого поведения при копировании каталога?
Разве рекурсивная копия каталога не является поведением по умолчанию; поведение мы хотим почти все время?
Такое ощущение, что это лишний флаг.
rm
Ответы:
Как работают файловые системы, каталог - это на самом деле не папка, содержащая файлы, а каталог - это файл, который содержит указатели на узлы «дочерних» файлов, связанных с ним. Это означает, что с точки зрения файловой системы файл - это файл, а каталог - это просто файл, содержащий список подключенных файлов.
Итак, с точки зрения командной строки, делая это:
В основном означало бы скопировать указанный файл
dir1
в новый файл с именемcopyDir1
. А что касается файловой системы, тоdir1
в любом случае это просто файл; тот факт, что это «каталог», будет очевиден только тогда, когда файловая система на самом деле проверяет,dir1
что это за куча битов на самом деле.-r
Флаг указывает файловую систему рекурсивно скатываются файл / дерево каталогов и копировать любые и все содержимое , которое может быть «ребенок» из этого файла на новое место.Теперь о том, почему это может показаться излишним или избыточным, это действительно сводится к историческим методам работы с файловыми системами. А также создание системы, которая защищена от всех типов ошибок, связанных с пользователем; случайный, а также преднамеренный.
То есть, допустим, у вас есть
~/bin
файл в вашем домашнем каталоге, который вы хотите скопировать, но случайно пропустили -~
потому что вы человек и делаете ошибки - так оно/bin
и есть:С «сетью безопасности»,
/bin
являющейся каталогом в сочетании с необходимостью-r
флага, вы избежите случайного копирования всего двоичного корня системы, в которой вы находитесь, в ваш домашний каталог. Если бы эта сеть безопасности не существовала, произошла бы небольшая или, возможно, крупная катастрофа.Логика здесь заключается в том, что в дни, предшествующие GUI (графические пользовательские интерфейсы), необходимо устанавливать логические / поведенческие соглашения, чтобы избежать создания пользователем ошибок, которые могут потенциально убить систему. И использование
-r
флага теперь является одним из них.Если это кажется излишним, то не нужно смотреть дальше, чем современная система графического интерфейса, которую можно поместить над файловыми системами Linux. Графический интерфейс пользователя решает основные пользовательские проблемы, такие как эта, позволяя легко перетаскивать файлы и каталоги.
Но в случае текстовых интерфейсов большая часть «пользовательского опыта» в этом мире - это, в основном, просто логические и основанные на практических условиях дорожные неровности, которые помогают держать пользователя под контролем, чтобы предотвратить потенциальную катастрофу.
Точно так же именно поэтому файловые системы Linux / Unix не имеют
777
разрешений иsudo
прав, установленных по умолчанию, и то, как настоящие системные администраторы вздрагивают, когда пользователь устанавливает777
разрешения или предоставляет всемsudo
права. Это основные вещи, которые нужно сделать, чтобы система была стабильной и как можно более «пользовательской»; любой, кто поспешит заморозить эти соглашения, скорее всего, нанесет ущерб их системе, даже не подозревая об этом.ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: Другой ответ здесь, на сайте Unix Stack Exchange, дает хорошее объяснение того, почему нерекурсивная копия каталога является проблематичной; Акцент мой.
Таким образом, если каталог - это просто файл с элементами inode, создание прямой копии этого файла будет эквивалентно тому, как будет работать жесткая ссылка. Который не тот, кто хочет.
источник
cp -r /bin
какcp-r ~/bin
. Сам флаг не предотвращает ошибок и не обязательно делает кого-то лучше, когда он осторожен. Если вы хотите предотвратить ошибки, команда cp может так же легко посмотреть на рассматриваемый узел и выдать подсказку, что-то вроде «Это каталог, хотите ли вы скопировать все содержимое в указанное место (y / п)?» Это было бы защитной сеткой . Требование -r для каталогов удерживает поток кода больше, чем что-либо еще.Это правда, что такое поведение мы хотим почти все время. Однако это не обязательно означает, что рекурсивное копирование должно быть поведением по умолчанию.
Я думаю, что причины
cp
действуют так, как это имеет корни в философии Unix . Unix предпочитает программы, которые делают одно и делают это хорошо , а также программы, которые просты как по интерфейсу, так и по реализации (иногда их называют хуже, лучше ).Ключевой частью головоломки здесь является понимание того, что
cp
не копирует каталоги -cp
копирует файлы (и только файлы). Если вы хотите скопировать каталог,cp
вызывайте себя рекурсивно , чтобы скопировать файлы в каждый каталог.Конечно, с точки зрения пользователя, разница между «копированием каталогов» и «рекурсивным копированием файлов» абсолютно ничтожна, но наличие этого интерфейса помогает реализации оставаться простой .
Если вы
cp
сможете копировать каталоги, у вас скоро появится желание добавить больше функций, которые имеют смысл только для каталогов - например, вы можете захотеть копировать только имена файлов, оканчивающиеся на.sh
. Это неизбежно приводит к раздутию и сбою функций, к которым мы привыкли в других операционных системах, что делает программное обеспечение медленным, сложным и подверженным ошибкам.Другое преимущество заключается в том, что наличие
-r
также помогает пользователю понять, что на самом деле происходит под интерфейсом. Приятным побочным эффектом этого является то, что изучение концепции рекурсивной операции избавит вас от некоторой работы, когда вы узнаете о других инструментах, которые ее поддерживают (напримерgrep
, например).Некоторые люди наверняка скажут вам, что предоставление подробностей реализации пользователю плохо , а наличие дополнительных функций - это хорошо . Мое намерение здесь - просто объяснить причину такого поведения, поэтому я не буду спорить в любом случае.
источник
Взаимодействие с каталогами гарантирует, что вы знаете, что взаимодействуете с каталогом, а не с одним файлом.
Например:
Итак, если вы хотите успешно скопировать папку, поскольку она подразумевает как папку, так и объекты, связанные со ссылкой на папку, вы должны обращаться с ней, как будто это набор файлов:
источник
Следствием изменения значения по умолчанию будет то, что тысячи сценариев оболочки сломаются. Это приводит к требованиям POSIX и SUS для хорошо известного поведения по умолчанию.
Причина заключается в историческом развитии команд cp, ln и mv (одинаковых двоичных файлов в большинстве старых систем UNIX) в различных ветвях UNIX. Когда
-r
появилось (cp
ранее не было возможности копировать каталоги; вот ранняя man-страница cp без-r
или-R
), были различные различия в обработке специальных файлов, символических ссылок и других капризов файловой системы.Из Открытой группы Base Specification Issue 7 :
На самом деле вы все еще будете видеть некоторых людей, регулярно использующих:
Потому что они не верят, что
cp -r
реализация будет той, к которой они привыкли на произвольной машине; Или потому что они хотятtar
поведения.источник
Сегодня это может быть неоптимальный пользовательский интерфейс, но это решение было принято примерно в 1970 году во время разработки UNIX, когда диск был значительно дороже. Миллионы сценариев оболочки зависят от его работы таким образом, и уже слишком поздно его менять.
Смотрите эту статью для оригинальной информации о дизайне.
источник
Очевидным преимуществом этого
-r
флага является то, что вы можетеcp * /target/dir
копировать только все файлы в исходном каталоге в целевой каталог, исключая (хотя и с предупреждением) все содержащиеся в нем каталоги.cp -r * /target/dir
скопировал бы все вместо этого, включая подкаталоги.источник
Этот флаг нужен только тогда, когда
cp
есть команда для копирования файлов и каталогов, а не только каталогов.Если бы существовала специальная команда для копирования каталогов, поведение по умолчанию, безусловно, было бы рекурсивной копией.
источник
mkdir
?Как уже упоминали другие, каталог - это просто другой тип файла (в отличие от обычного файла), который обычно «содержит» (указывает на) другие файлы. Он может содержать подкаталоги, к которым относится то же самое ...
Поэтому, если вы копируете каталог (с точки зрения пользователя), вы действительно копируете кучу файлов (с точки зрения файловой системы) (обычные файлы, файлы каталогов, символические ссылки, ...), и для каждого файла каталога вы рекурсивно повторяете это процесс. Поскольку копирование каталога по определению является рекурсивным процессом, вызывается аргумент cp
--recursive
.Конечно, очень легко создать ярлык команды в вашей пользовательской среде (поместите это в ваш файл .profile / .bashrc, чтобы сделать его постоянно доступным):
Или, может быть, лучше:
Таким образом, вы можете скопировать каталог, используя
cpa dir1 copyDir1
его, и он будет не только печатать то, что копируется, но и применять права доступа к файлам.И поскольку кто-то упомянул, что cp может теоретически определить, что исходный файл является каталогом, и спросить, следует ли ему копировать его рекурсивно, вот краткое предложение:
Это всего лишь дешевая оболочка cp. Он всегда сохраняет все метаданные (т. Е. Копирует время изменения файла, правильно копирует символические ссылки и т. Д.), И если вы пытаетесь скопировать каталог, он спрашивает, следует ли ему копировать его (рекурсивно).
источник