установить права на чтение и запись для папки и всех ее родительских каталогов

18

Мне нужно установить права на чтение и запись для rootпользователя в каталог subfolderNи все его родительские папки до root.

Я могу сделать это руками:

$ sudo chmod +rx /root/subfolder1/subfolder2/subfolderN
$ sudo chmod +rx /root/subfolder1/subfolder2
$ sudo chmod +rx /root/subfolder1
$ sudo chmod +rx /root

Но если Nбольшой, я устал. Как сделать это автоматически одной командой?

Максим Ефремов
источник
Вы действительно не должны делать /rootмир читабельным.
Стефан Шазелас

Ответы:

23

Это можно легко сделать в оболочке, начиная с subdir и двигаясь вверх:

f=/root/subfolder1/subfolder2/subfolderN
while [[ $f != / ]]; do chmod +rx "$f"; f=$(dirname "$f"); done;

Это начинается с любого файла / каталога, который вы также установили для f, и работает с каждым родительским каталогом, пока не встретится "/" (или с тем, что для строки в условии цикла установлено). Это не chmod "/".

wingedsubmariner
источник
Хорошо, я знал, что без необходимости усложняю вещи с Perl.
Тердон
Но что, если fэто относительный путь, и я хочу остановиться на том, к чему он относится вместо /?
StackExchange для всех
@ StéphaneChazelas Спасибо. Если $fэто foo/barбудет $fкогда - нибудь изменится .? Да, dirnameделает это. Спасибо
StackExchange за все
1
@Tim преобразует относительный путь в абсолютный путь перед сохранением в f с помощью команды "f =` readlink -f <
lative_path
6

С csh, tcsh, ksh, zsh, bash, fishили yash -o braceexpand:

sudo chmod +rx /root{,/subfolder1{,/subfolder2{,/subfolderN}}}

С zsh:

f=/root/subfolder1/subfolder2/subfolderN
until [[ $f = / ]] {chmod +rx $f; f=$f:h;}

Или вы можете определить функцию квалификатора glob, например:

explode() {
  reply=()
  until [[ $REPLY = [./] ]] {
    reply+=$REPLY
    REPLY=$REPLY:h
  }
}

Используется, например, как:

$ echo chmod +rx subfolder1/subfolder2/subfolderN(+explode)
chmod +rx subfolder1 subfolder1/subfolder2 subfolder1/subfolder2/subfolderN  

Обратите внимание, что chmod +rxэто зависит от Umask. Если вы umaskне включите 007, это сделает /rootкаталог доступным для чтения и доступным для мира, что является плохой идеей. /rootкак правило, для личных вещей суперпользователя, плохая идея разоблачить это.

Стефан Шазелас
источник
Не могли бы вы объяснить , что ведущий ,в {,/subfolder}делает?
Тердон
Это создает чередование, где первая строка пуста, а вторая /subfolder; так /root{,/subfolder}производит /rootи/root/subfolder
tripleee
Примечательно, что это не переносимо в POSIXsh
tripleee
2

Ну, вы можете сделать что-то более сложное, например:

echo "/root/subfolder1/subfolder2/subfolderN" | 
 perl -anF'/' -e 'while($#F>0){@b=join("/",@F);`chmod +rx @b`; pop @F}' 

Чтобы увидеть, что это будет делать, замените chmodвызов на print:

$ echo "/root/subfolder1/subfolder2/subfolderN" | 
 perl -alnF'/' -e 'while($#F>0){@b=join("/",@F);print "chmod +rx @b"; pop @F}' 
chmod +rx /root/subfolder1/subfolder2/subfolderN
chmod +rx /root/subfolder1/subfolder2
chmod +rx /root/subfolder1
chmod +rx /root
Тердон
источник
1

Я не знаю, что вы пытаетесь сделать, но лучше, чем вы не принимаете рекурсивную легкомысленность . Тем не менее, прочитайте фактический ответ:

Хм ... почему бы просто не использовать рекурсивный.

sudo chmod -R +rx /root

Или, если вам не нравится, вы можете дать chmodнесколько каталогов:

sudo chamod +rx /root /root/subfolder1 /root/subfolder1/subfolder2 /root/subfolder1/subfolder2/subfolderN
Braiam
источник
4
Это не та же самая операция, хотя. chmod -R /rootменяет все под /root- включая обычные файлы и все каталоги. Речь идет об изменении только одной цепочки каталогов.
200_success
@ 200_success, но это не единственный ответ;)
Брайам
Вопрос не в рекурсии, а в том, как установить разрешения для цепочки родительских папок, чтобы разрешить выборочный доступ к подпапке. Сказать, что это не единственный ответ, все равно, что сказать, что вождение автобуса через вашу стену - это еще один способ сделать дверь.
JMC