Я случайно chmod -R + x по каталогу. Как восстановить правильные разрешения?

20

Ну, чтобы быть конкретным, это было chmod -R 755. Теперь каждый файл исполняемый, чего я не хочу. Я думаю, что я должен смотреть на первые два байта каждого файла для #!, но охватит ли это все? Должен ли я вместо этого использовать, fileчтобы посмотреть на все и основывать свое решение на этом? Или, более вероятно, есть еще лучший способ сделать это?

Каков предпочтительный способ рекурсивного просмотра каталога и установки -x для файлов, которые «не должны быть» исполняемыми?

Ларри Ван
источник
Вы делали это в /или другом каталоге?
gvkv
1
@ gvkv: Нет /, каталог полностью принадлежит мне.
Ларри Ван
1
@ Ларри, в будущем вам, вероятно, следует использовать какой-то вариант + x вместо того, чтобы изнасиловать все разрешения и, возможно, вызвать запись во все файлы.
ксенотеррацид
@xenoterracide: Согласен. Что я действительно хотел, так это дать группе те же права, что и у меня (что в итоге и произошло!), Я просто не задумывался, прежде чем печатать.
Ларри Ван
Сколько файлов мы говорим? Сколько должно быть исполняемого? Есть ли способ узнать по именам файлов?
Дэвид Торнли

Ответы:

15

Здесь нет волшебной пули. Разрешения несут информацию, которая не всегда избыточна.

Если бы вы сделали это в системном каталоге, ваша система была бы в очень плохом состоянии, потому что вам пришлось бы беспокоиться о битах setuid и setgid, а также о файлах, которые не должны быть доступны для чтения всем пользователям, и о файлах. которые должны быть написаны группой или миром.

В каталоге для каждого пользователя вам нужно беспокоиться о файлах, которые не должны быть доступны для чтения всем пользователям. Там никто не сможет тебе помочь.

Что касается выполнимости, хорошее эмпирическое правило состояло бы в том, чтобы сделать все, что не похоже на его выполнение, неисполнимым. Ядро может выполнять сценарии с первыми двумя байтами #!, двоичные файлы ELF, первые четыре байта \x7fELFкоторых \x7f- это где байт со значением 12, и несколько более редких типов файлов (a.out, все, что зарегистрировано в binfmt_misc). Следовательно, следующая команда должна восстановить ваши разрешения до приемлемого состояния (предполагается, что bash 4 или zsh, в противном случае используйте findдля просмотра дерева каталогов; предупреждение, введенное непосредственно в браузере):

for x in **/*; do
  if ! [ -f "$x" ]; then continue; fi # skip all but regular files
  case $(head -c 4 "$x") in
    "#!"??) :;; # skip script
    "\x7fELF") :;; # skip ELF executable
    *) chmod a-x "$x";;
  esac
done

Обратите внимание, что существует простой способ резервного копирования и восстановления разрешений дерева каталогов в Linux и, возможно, в других устройствах с поддержкой ACL:

getfacl -R >saved-permissions
setfacl --restore=saved-permissions
Жиль "ТАК - перестань быть злым"
источник
Благодарность! К счастью, я думаю, что все попадает в эти две категории. Если что-то пропустит, я смогу разобраться с этим позже.
Ларри Ван
Имейте в виду, что **/*требует globstar.
Крис Даун
Я бы порекомендовал два изменения в этом скрипте. findВо- первых, используйте, а не Globstar; два, вместо того, чтобы смотреть на голову, используйте fileкоманду, чтобы увидеть, что это такое, и оттуда ответвляться.
Шадур
@Shadur findменее надежен globstar, globstarпредпочтителен почти в каждом случае.
Крис Даун
1
@Gilles Предпочтительнее, как в «если он у вас есть, он намного лучше», он не только быстрее, но и более надежен (и не имеет неожиданных SNAFU).
Крис Даун
6

Я верю, что вы захотите что-то вроде

find dir -type f -exec chmod ugo-x '{}' +

Это ищет все обычные файлы, рекурсивно в dir (исключая каталоги и устройства) и удаляет исполняемый бит.

Я бы начал здесь, а затем продолжил свой путь к созданию файлов, которые должны быть исполняемыми, исполняемыми.

Следующее должно работать точно так, как вы просили (он найдет все обычные файлы, grep их для #! И затем удалит биты x, если не найден)

find . -type f | xargs grep -L #! | xargs chmod ugo-x

возможно, лучшая версия выше (меньше труб)

find . -type f -exec grep -L #! '{}' + | xargs chmod ugo-x 
xenoterracide
источник
3
Сделайте это grep -L '^#!'по крайней мере (кавычки необходимы и ^ограничиваются соответствием в начале строки), но это все еще слишком разрешительно, поскольку оно соответствует #!любой строке. Использование не xargsбудет работать с именами файлов, содержащими пробелы или символы кавычек; использовать xargs -d '\n'(требуется GNU xargs).
Жиль "ТАК ... перестать быть злым"
0

Ну, без строки shebang, файл будет выполнен как скрипт оболочки, номинально с /bin/sh. Вы считаете, что это хорошее начало, и при условии, что рассматриваемый каталог не содержит критически важных файлов, вероятно, нет большого риска для выполнения некоторых grepи chmodкомбинированных. Вы можете столкнуться с ложными срабатываниями, т. Е. С файлами со строкой Шебанга, для которых не предназначен набор исполняемых битов, но без знания дополнительной информации о назначении каталога, только вы можете решить, представляет ли это существенную экзистенциальную угрозу вашему система и / или данные.

gvkv
источник
Меня беспокоит не столько ложные срабатывания, сколько ложные негативы. Есть двоичные файлы, с которых я не думаю, что начать #!.
Ларри Ван