
У меня есть скрипт, который я запускаю для исправления владельца файла и разрешений после rsync. Вопросы об оптимальном способе выполнения моей задачи в сторону, интересно, есть ли способ запустить chmod
и chown
в то же время?
В текущей версии моего скрипта я find
дважды отправляю файлы.
find /var/www/mysite -exec chown www-data:www-data {} \;
find /var/www/mysite -type f -exec chmod 775 {} \;
Я подумал, что было бы неплохо, если бы я мог изменить и разрешения, и владельца/группу одной командой. После некоторого гугления я был удивлен, узнав, что такой команды, аргумента или опции не существует.
Могу ли я одновременно изменить права доступа и владельца, чтобы не find
изменять каждый файл дважды?
РедактироватьРедактирование сообщества или пост или что-то еще предполагает, что этот вопрос является дубликатом«Изменить все разрешения для папок с помощью одной команды». Этот вопрос отличается тем, что он касается измененияобаразрешенияи владениев то же время, а не просто разрешения.
решение1
Вы можете передать несколько команд exec:
find /var/www/mysite -exec chown www-data:www-data {} \; \
-type f -exec chmod 775 {} \;
решение2
Вы можете добавить эквивалентные параметры в свою rsync
команду:
rsync <your_options> --chown www-data:www-data --chmod=F775 <source> <destination>
Вы можете использовать префикс F
in --chmod
для файлов и D
каталогов.
решение3
Для полноты картиныxargsтакже может делать много интересных вещей в конвейерах.
find . -type f -print0 | xargs -0 -I VAR -- sh -c 'chmod 775 "VAR" && chown www-data:www-data "VAR" '
Это создает поток имен файлов (не имен каталогов) с нулями в качестве разделителей, что позволяет справиться с пробелами в именах файлов.
-0
говорит xargs о необходимости разделения входных данных по значению null.
-I VAR
говорит использовать VAR
в качестве «имени переменной» вместо {}
--
и все, что после него, — это то, что нужно запустить для каждой строки
Это может быть более читабельно, но это будет запускать новую оболочку для каждого запуска двойной команды.
решение4
Если вас беспокоит возможность find
повторного запуска каждого файла, вам также следует побеспокоиться о количестве ветвлений, которые возникнут при запуске комбинации команд через xargs.
Люди часто забывают, что в Perl есть эквиваленты для многих из этих базовых команд оболочки. Вот один из способов, как я бы это сделал (проверено):
find | perl -lne 'chown 1001,1001, $_; -d $_ ? chmod(0755, $_) : chmod(0644, $_)'
Вам придется использоватьчисловойuid, gid и mode, но подумайте вот о чем:это вообще не разветвляется(за пределами одного find
и того же perl
).
И вам не нужно хорошо знать Perl, чтобы в нем разобраться.
chown и chmod достаточно понятны. -d
они такие же, как в shell [
или test
команде, а тернарный оператор foo ? bar : baz
не является уникальным для Perl. (В качестве бонуса вы можете использовать различные режимы для каталогов и файлов..)
На самом деле, это опции, которые могут потребовать объяснения, если вы новичок в Perl. Немного упрощенно:
- означает
-n
«запустить это один раз для каждой строки STDIN, установив$_
на строку» -l
заставляет исчезнуть перевод строки в конце каждой строки (потому что в противном случае он становится частью$_
)-e
знакомо тем, кто знаетsed
; там говорится, что это выражение для оценки/выполнения.