Як я можу змусити хору працювати рекурсивно?


285

У мене є каталог, який називається, pdfsщо містить купу під- і під-підкаталогів. Я хочу змінити право власності на всі файли PDF у всіх підпапках. Я просто спробував це:

chown -R someuser:somegroup *.pdf

... але це не змінило право власності на PDF-файли у підкаталогах. Користувач і група існують.

Відповідно до сторінки man для chown, це -Rмає означати рекурсивний:

-R, --recursive
          operate on files and directories recursively

Що я пропускаю?

Відповіді:


291

Рекурсивний режим працює лише в каталогах, а не в файлах. Використовуючи глобул '* .pdf', оболонка передає список файлів до chown, який бачить, що це файли, і змінює дозволи на файли, які він бачить, і все.

Пам'ятайте, що в оболонках глобус оцінюється оболонкою, а не командою. Якщо глоб відповідає файлам, вони передаються команді, і команда ніколи не знає, що глобус існував. (Це відрізняється від того, як використовується командний рядок Windows). Якщо у вас є реж, зі змістом приблизно так:

machine:$ ls -F
file1.pdf  file2.pdf  other.txt  subdir/

І ви набрали:

chown -R someuser:somegroup *.pdf

Оболонка спочатку складе список: file1.pdf file2.pdf

а потім запустіть свою команду:

chown -R someuser:somegroup file1.pdf file2.pdf

Дивіться, немає каталогу, на який можна діяти -R. Це робить те, що ви просили, - змінити право власності на два файли в командному рядку, ігноруючи цей вигадливий прапор -R.

Щоб зробити те, що ви хочете, використовувати "* .pdf" як зразок для цього каталогу та підкаталогів, ви можете використовувати findфайли, які відповідають шаблону імен файлів (або багатьох інших критерий) і переходити до підкоманди

find . -type f -name '*.pdf' | xargs chown someuser:somegroup

Це починається з поточного режиму "." шукати файли (тип файлу f) шаблону імен '*.pdf'потім переходить до xargs, який будує командний рядок до chmod. Зауважте лапки навколо шаблону '*.pdf', пам’ятайте, що оболонка створить глобус, якщо зможе, але ви хочете, щоб шаблон передався find, тому вам потрібно його навести.

Оскільки в іменах файлів можуть бути пробіли, ви хочете використовувати трюк, щоб зробити його ім'ям файлів із пробілами безпечним:

find . -type f -name '*.pdf' -print0 | xargs -0 chown someuser:somegroup

У bash 3 і нижче це саме те, що вам потрібно зробити. Більш потужний глобус доступний в баш-4 (з shopt -s globstar) та інших оболонках. Те ж саме в zsh, використовуючи рекурсивний глобул **:

chown -R someuser:somegroup ./**/*.pdf

1
Відредаговано так, щоб відобразити, що баш 4 з shopt -s globstarрекурсивним глобалізацією.
kojiro

@kojiro дякую! як ви можете сказати, я все ще використовую bash3
Rich

2
На сторінці man, показаній оригінальним плакатом, я виявив, що chown -R дійсно змінив власника папок І файлів. Не потрібно знаходити. Використання монетного двору 15.
gwideman

@gwideman Я знаю, що це старе ... Але так, звичайно -R робить рекурсивним. У ОП щойно виникли проблеми з дуже специфічним типом рекурсії, розширення та «тип файлу - файл», відфільтрований
Річ Хомолка

@RichHomolka Ах. ОП сказав, що файли знаходяться в каталозі під назвою "pdfs", тому я припустив, що проблема полягає в тому, як вказати pdfs як каталог для повторного запису, і що всі файли, що містяться, були pdfs, тому не потрібно вибирати їх спеціально. Але ви цілком можете мати рацію, якщо завдання полягає в тому, щоб вибрати лише файли pdf, а інші залишити без змін.
gwideman

52
chown -R someuser:somegroup /your/folder/here/*

Це стосуватиметься chown до всіх файлів та всіх підкаталогів та підкаталогів зазначеної папки. Використовуйте обережно.


2
Якось sudo chown -R user ./працював на мене, але sudo chown -R user ./*не так
Слав

1
Я знаю, що це по-старому, але хоч це відповідає заголовку, але не відповідає на питання. Це насправді трохи гірше, ніж те, що ОП вже намагалася.
Багата Гомолка

2
@RichHomolka Привізши сюди саме через назву питання, я дуже радий знайти цю відповідь.
Фелікс Ганьон-Греньє

@ FélixGagnon-Grenier досить справедливо. Якщо ця відповідь працює для вас, я дуже радий. Але це не спрацювало з початковим питанням.
Багата Гомолка

Здається, це не працює для точкових файлів, таких як .env.
Райан

14

Ви можете скористатися findутилітою:

find . -name '*.pdf' -exec chown someuser:somegroup {} +

Будь ласка, не забувайте цитати навколо *.pdf. Інакше оболонка спробує розширити її. Це означає, що оболонка вже замінить *.pdfназви всіх файлів PDF, що знаходяться в поточному каталозі. Але це не те, чого ти хочеш. Ви хочете знайти PDF-файли, розташовані у підкаталогах. Btw. У цьому також проблема вашої chownкоманди.


1
Довелося шукати +акуратний трюк для виконання. -exec command {} +Цей варіант дії -exec виконує вказану команду на вибраних файлах, але командний рядок будується додаванням кожного вибраного імені файлу в кінці; загальна кількість викликів команди буде значно меншою, ніж кількість відповідних файлів. Командний рядок побудований приблизно так само, як xargsбудує його командні рядки. Лише один екземпляр {}дозволений в межах команди. Команда виконується в початковому каталозі.
Патрік М

@PatrickM одна (другорядна) інша перевага до + vs; .... плюс - це не мета-символ оболонки, і його не потрібно уникати
Rich Homolka

6

Команда

chown -R someuser:somegroup *.pdf

буде рекурсувати вниз каталоги лише в тому випадку, якщо ім'я каталогу закінчується в .pdf. Вам потрібно щось на зразок:

find . -name "*.pdf" -exec chown someuser:somegroup {} \;

Технічно це буде лише на один рівень вниз. чи називаєте ви справжньою рекурсією чи ні - це вправа для користувача :)
Rich Homolka

1

щоб змінити право власності на каталог рекурсивно, просто використовуйте:

sudo chown -R <username>:<groupname> <dir name>

тут ім'я користувача = новий користувач, який повинен бути власником каталогу

groupname = нова група, яка повинна бути власником каталогу

кожен файл / каталог має власника користувача та власника групи


Це не робить того, що просив ОП. Це змінює право власності на все, OP попросив конкретний набір файлів.
Багата Гомолька

0

Я використовую treeнатомість:

 sudo tree -fai ~/.blabla  | xargs -L1 -I{} sudo chown youruser:youruser {}

Також слідкуйте за тим, щоб не запускати рекурсивний chown або chmod в каталозі '/' або іншому системному каталозі.


0

Щоб стати власником усіх файлів у каталозі, використовуйте

find directory -type f -name '*' | sudo xargs -d '\n' chown $USER

замість

sudo chown $USER directory\*

або

sudo chown --recursive $USER directory

які можуть не працювати, якщо в арсеналі є занадто багато аргументів, створених * (занадто багато файлів у каталозі) або які не роблять, що потрібно, відповідно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.