#!/bin/sh
Линуксоид на велосипеде с моторчиком
Рекурсивные операции с файлами в Linux
Иногда возникает путаница между опциями -r и -R, каждая из которых в разных программах может означать рекурсивную обработку файлов в найденных каталогах. А может означать нечто совершенно противоположное или работать не так, как этого ожидал пользователь. Попробуем разобраться, в каких случаях что используется.
Эпиграф
— Это новый «Гарри Поттер». Я заказал версии для детей и взрослых, чтобы проверить, что в тексте нет различий.
Морис Мосс, The IT Crowd.
chmod
Ключ -r у chmod интерпретируется как «запретить всем чтение файла», а 755 в данном случае рассматривается как название файла, у которого изменяются права. Поскольку в подавляющем большинстве случаев файла с таким названием в текущей директории отсутствует, то команда возвращает ошибку.
chown, chattr, chgrp
У вышеперечисленных команд опция -r просто отсутствует. Для рекурсивной обработки директорий необходимо использовать опцию -R. Очевидно, так сделано из солидарности с «братской» командой chmod
Несмотря на то, что в странице документации cp из GNU coreutils сказано, что опции -r и -R равнозначны и означают рекурсивную обработку встречающихся директорий, опция -r, в отличие от -R, не соответствует стандарту POSIX и ее указание может повлечь за собой неожиданные последствия в случае, если очередной копируемый объект является чем-то отличным от обычного файла или директории (например, символической ссылкой, fifo или сокетом). В таких случаях некоторые реализации cp просто копируют содержимое ссылки/fifo, тогда как при -R такие объекты пересоздаются заново. Раньше такое поведение было присуще GNU cp, о чем до сих пор имеется свидетельство в русском man cp. Что касается более правильных (чем Linux) систем, то, например, в BSD-версии cp опция -r работает в «режиме совместимости», т.е. не создает символическую ссылку заново, а копирует содержимое в файл с тем же именем.
Ключ -r команды ls означает «обратный порядок сортировки»
Правильно:
rm, grep
Зато в следующих случаях употребление -r/-R равнозначно:
Что касается grep, то, во-первых, обе опции не соответствуют POSIX (но, похоже, присутствуют во всех реализациях) Во-вторых, иногда возникает путаница между опциями -i (игнорировать регистр) и -I (пропускать двоичные файлы). Но это уже тема для другого разговора 🙂
Прочие команды
Поскольку команд, в том или ином виде поддерживающих рекурсивную обработку каталогов, набралось довольно много, то я попробовал свести их в одну таблицу.
команда | -r | -R |
---|---|---|
chacl | рекурсия | удаление ACL только с файлов |
setfacl | не поддерживается | рекурсия |
cvs | номер ревизии | рекурсия |
diff | рекурсия | не поддерживается |
gzip/gunzip | рекурсия | не поддерживается |
zip | рекурсия | рекурсия, начиная с текущей директории (см. man zip, там есть существенная разница в обработке -r и -R) |
rsync | рекурсия | использование относительных путей |
wget | рекурсия | указывает список отвергаемых шаблонов |
Заключение
Как видно, в большинстве случаев для указания рекурсии используется опция -r в нижнем регистре, в противовес стандартным утилитам, для которых характерно все же -R. Поэтому совет один: в случае сомнения смотрите в man, там все написано 🙂
Постскриптум
По абзацу про cp видно, что русская документация в некоторых дистрибутивах (не будем показывать пальцем на Debian и Ubuntu) не соответствует реальному положению дел. В частности, несмотря на то, что в jaunty используется GNU coreutis 6.10, русский man описывает cp версии 4.1. Желающие могут самостоятельно сравнить свою версию man 1 cp с локализованной. Другими словами, русская страница документации cp в силу своей древности вводит пользователя в заблуждение, т.е. врёт. По этой причине я рекомендую сделать apt-get remove manpages-ru.
2 комментария
- Comment by anon :
> По этой причине я рекомендую сделать apt-get remove manpages-ru
Плюсую. Помню как потерял с час времени, из за феерично переведенного мана:
If from is not NULL, and the underlying protocol provides the source address, this source address is filled in.
Если параметр from не равен NULL, а сокет не является ориентированным на соединения, то адресотправителя в сообщении не заполняется.
scp неплохо было бы упомянуть. Нигде проблем с -r/-R не испытывал, только в scp почему-то постоянно пишу -R.
Источник
Почему -r рекурсивно необходимо при копировании каталога в Linux?
Мой вопрос: почему при создании копии каталога необходимо использовать флаг -r (рекурсивный)? Т.е. зачем это делать:
Когда бы я не хотел такого поведения при копировании каталога?
Разве рекурсивная копия каталога не является поведением по умолчанию; поведение мы хотим почти все время?
Такое ощущение, что это лишний флаг.
8 ответов 8
Как работают файловые системы, каталог — это на самом деле не папка, содержащая файлы, а каталог, который представляет собой файл, содержащий указатели inode на «дочерние» файлы, связанные с ним. Это означает, что с точки зрения файловой системы файл — это файл, а каталог — это просто файл, содержащий список подключенных файлов.
Итак, с точки зрения командной строки, делая это:
В основном это означало бы копирование файла с именем dir1 в новый файл с именем copyDir1 . А что касается файловой системы, то dir1 в любом случае является просто файлом; тот факт, что это «каталог», будет очевиден только тогда, когда файловая система на самом деле проверяет dir1 чтобы увидеть, какова эта куча битов.
Флаг -r указывает файловой системе рекурсивно свернуть дерево файлов / каталогов и скопировать любое и все содержимое, которое может быть «потомком» этого файла, в новое место.
Теперь о том, почему это может показаться излишним или избыточным, это действительно сводится к историческим методам работы с файловыми системами. А также создание системы, которая защищена от всех типов ошибок, связанных с пользователем; случайный, а также преднамеренный.
То есть, допустим, у вас есть файл
/bin в вашем домашнем каталоге, который вы хотите скопировать, но случайно пропустили
— потому что вы человек и делаете ошибки — так что просто /bin вот так:
Поскольку «сеть безопасности» /bin является каталогом в сочетании с необходимостью флага -r вы избежите случайного копирования всего двоичного корня системы, в которой вы находитесь, в ваш домашний каталог. Если бы эта сеть безопасности не существовала, произошла бы небольшая или, возможно, крупная катастрофа.
Логика здесь заключается в том, что в дни, предшествующие GUI (графические пользовательские интерфейсы), необходимо устанавливать логические / поведенческие соглашения, чтобы избежать создания пользователем ошибок, которые могут потенциально убить систему. И использование флага -r теперь является одним из них.
Если это кажется излишним, то не нужно смотреть дальше, чем современная система графического интерфейса, которую можно поместить над файловыми системами Linux. Графический интерфейс пользователя решает основные пользовательские проблемы, подобные этой, позволяя легко перетаскивать файлы и каталоги.
Но в случае текстовых интерфейсов большая часть «пользовательского опыта» в этом мире — это, в основном, просто логические и основанные на практических условиях дорожные неровности, которые помогают держать пользователя под контролем, чтобы предотвратить потенциальную катастрофу.
Точно так же именно поэтому файловые системы Linux/Unix не имеют разрешений 777 и прав sudo установленных по умолчанию, и то, как настоящие системные администраторы вздрагивают, когда пользователь устанавливает разрешения 777 или предоставляет всем права sudo . Это основные вещи, которые нужно сделать, чтобы система была стабильной и как можно более «пользовательской»; Любой, кто спешит замкнуть эти соглашения, скорее всего, нанесет ущерб их системе, даже не подозревая об этом.
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: Другой ответ здесь, на сайте Unix Stack Exchange, дает хорошее объяснение того, почему нерекурсивная копия каталога является проблематичной; акцент мой.
Что ж, без флага -R возможно только копирование файлов, потому что довольно необычно, что кто-то хочет нерекурсивно копировать каталог: нерекурсивная копия просто привела бы ко второму имени для каталога, указывая непосредственно на та же структура каталогов. Поскольку это редко то, что люди хотят, и на самом деле существует отдельная программа, которая делает это (ln), нерекурсивная копия каталогов не допускается.
Таким образом, если каталог — это просто файл с элементами inode, создание прямой копии этого файла будет эквивалентно тому, как будет работать жесткая ссылка. Что не то, что кто-то хочет.
Источник
Почему -r рекурсивно необходимо при копировании каталога в Linux?
У меня вопрос: почему -r при создании копии каталога необходимо использовать флаг (рекурсивный)? Т.е. зачем это делать:
Когда бы я не хотел такого поведения при копировании каталога?
Разве рекурсивная копия каталога не является поведением по умолчанию; поведение мы хотим почти все время?
Такое ощущение, что это лишний флаг.
Как работают файловые системы, каталог — это на самом деле не папка, содержащая файлы, а каталог — это файл, который содержит указатели на узлы «дочерних» файлов, связанных с ним. Это означает, что с точки зрения файловой системы файл — это файл, а каталог — это просто файл, содержащий список подключенных файлов.
Итак, с точки зрения командной строки, делая это:
В основном означало бы скопировать указанный файл dir1 в новый файл с именем copyDir1 . А что касается файловой системы, то dir1 в любом случае это просто файл; тот факт, что это «каталог», будет очевиден только тогда, когда файловая система на самом деле проверяет, dir1 что это за куча битов на самом деле.
-r Флаг указывает файловую систему рекурсивно скатываются файл / дерево каталогов и копировать любые и все содержимое , которое может быть «ребенок» из этого файла на новое место.
Теперь о том, почему это может показаться излишним или избыточным, это действительно сводится к историческим методам работы с файловыми системами. А также создание системы, которая защищена от всех типов ошибок, связанных с пользователем; случайный, а также преднамеренный.
То есть, допустим, у вас есть
/bin файл в вашем домашнем каталоге, который вы хотите скопировать, но случайно пропустили —
потому что вы человек и делаете ошибки — так оно /bin и есть:
С «сетью безопасности», /bin являющейся каталогом в сочетании с необходимостью -r флага, вы избежите случайного копирования всего двоичного корня системы, в которой вы находитесь, в ваш домашний каталог. Если бы эта сеть безопасности не существовала, произошла бы небольшая или, возможно, крупная катастрофа.
Логика здесь заключается в том, что в дни, предшествующие GUI (графические пользовательские интерфейсы), необходимо устанавливать логические / поведенческие соглашения, чтобы избежать создания пользователем ошибок, которые могут потенциально убить систему. И использование -r флага теперь является одним из них.
Если это кажется излишним, то не нужно смотреть дальше, чем современная система графического интерфейса, которую можно поместить над файловыми системами Linux. Графический интерфейс пользователя решает основные пользовательские проблемы, такие как эта, позволяя легко перетаскивать файлы и каталоги.
Но в случае текстовых интерфейсов большая часть «пользовательского опыта» в этом мире — это, в основном, просто логические и основанные на практических условиях дорожные неровности, которые помогают держать пользователя под контролем, чтобы предотвратить потенциальную катастрофу.
Точно так же именно поэтому файловые системы Linux / Unix не имеют 777 разрешений и sudo прав, установленных по умолчанию, и то, как настоящие системные администраторы вздрагивают, когда пользователь устанавливает 777 разрешения или предоставляет всем sudo права. Это основные вещи, которые нужно сделать, чтобы система была стабильной и как можно более «пользовательской»; любой, кто поспешит заморозить эти соглашения, скорее всего, нанесет ущерб их системе, даже не подозревая об этом.
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: Другой ответ здесь, на сайте Unix Stack Exchange, дает хорошее объяснение того, почему нерекурсивная копия каталога является проблематичной; Акцент мой.
Что ж, без флага -R возможно только копирование файлов, потому что довольно необычно, что кто-то хочет нерекурсивно копировать каталог: нерекурсивная копия просто привела бы ко второму имени для каталога, указывая непосредственно на та же структура каталогов. Поскольку это редко то, что люди хотят, и на самом деле существует отдельная программа, которая делает это (ln), нерекурсивная копия каталогов не допускается.
Таким образом, если каталог — это просто файл с элементами inode, создание прямой копии этого файла будет эквивалентно тому, как будет работать жесткая ссылка. Который не тот, кто хочет.
/bin . Сам флаг не предотвращает ошибок и не обязательно делает кого-то лучше, когда он осторожен. Если вы хотите предотвратить ошибки, команда cp может так же легко посмотреть на рассматриваемый узел и выдать подсказку, что-то вроде «Это каталог, хотите ли вы скопировать все содержимое в указанное место (y / п)?» Это было бы защитной сеткой . Требование -r для каталогов удерживает поток кода больше, чем что-либо еще.
Это правда, что такое поведение мы хотим почти все время. Однако это не обязательно означает, что рекурсивное копирование должно быть поведением по умолчанию.
Я думаю, что причины cp действуют так, как это имеет корни в философии Unix . Unix предпочитает программы, которые делают одно и делают это хорошо , а также программы, которые просты как по интерфейсу, так и по реализации (иногда их называют хуже, лучше ).
Ключевой частью головоломки здесь является понимание того, что cp не копирует каталоги — cp копирует файлы (и только файлы). Если вы хотите скопировать каталог, cp вызывайте себя рекурсивно , чтобы скопировать файлы в каждый каталог.
Конечно, с точки зрения пользователя, разница между «копированием каталогов» и «рекурсивным копированием файлов» абсолютно ничтожна, но наличие этого интерфейса помогает реализации оставаться простой .
Если вы cp сможете копировать каталоги, у вас скоро появится желание добавить больше функций, которые имеют смысл только для каталогов — например, вы можете захотеть копировать только имена файлов, оканчивающиеся на .sh . Это неизбежно приводит к раздутию и сбою функций, к которым мы привыкли в других операционных системах, что делает программное обеспечение медленным, сложным и подверженным ошибкам.
Другое преимущество заключается в том, что наличие -r также помогает пользователю понять, что на самом деле происходит под интерфейсом. Приятным побочным эффектом этого является то, что изучение концепции рекурсивной операции избавит вас от некоторой работы, когда вы узнаете о других инструментах, которые ее поддерживают (например grep , например).
Некоторые люди наверняка скажут вам, что предоставление подробностей реализации пользователю плохо , а наличие дополнительных функций — это хорошо . Мое намерение здесь — просто объяснить причину такого поведения, поэтому я не буду спорить в любом случае.
Источник