Необходимо исправить права доступа к файлам в домашнем каталоге пользователя.

24

У кого-нибудь есть инструмент или скрипт, который рекурсивно исправляет права доступа к файлу в каталоге?

На машине с Ubuntu Linux куча файлов была скопирована на USB-диск с полными 777 разрешениями (пользователь, группа, другое - чтение, запись, выполнение) по ошибке. Я хочу положить их обратно в каталог пользователей исправлено.

Каталоги должны быть 775, а все остальные файлы могут быть 664. Все файлы являются изображениями, документами или MP3-файлами, поэтому ни один из них не должен быть исполняемым. Если бит каталога установлен, то он требует выполнения, в противном случае ему просто нужны пользователь и группа, чтение и запись.

Я подумал, что стоит проверить, существует ли такая утилита, прежде чем взламывать сценарий оболочки :)

mlambie
источник
вот один, который я сделал ранее: http://timwise.blogspot.com/2008/08/reseting-home-folder-permissions-in.html
Тим Абелл

Ответы:

51

Это должно сделать трюк:

find /home/user -type d -print0 | xargs -0 chmod 0775
find /home/user -type f -print0 | xargs -0 chmod 0664
Freiheit
источник
1
+1 за использование -print0 / xargs -0 :-).
Слеське
14

find может добиться цели только с -exec:

find /home/user -type f -exec chmod 0664 {} \;
find /home/user -type d -exec chmod 0775 {} \;

чтобы предотвратить появление find для chmod для каждой записи:

find /home/user -type f -exec chmod 0664 {} +
find /home/user -type d -exec chmod 0775 {} +

(это фактически вызывает chmod один раз со списком всех файлов в качестве параметров, а не один chmod на файл)

ThorstenS
источник
6
Это медленнее, чем использование xargs, так как вы разветвляете chmod для каждого файла, где xargs будет запускать процесс chmod с таким количеством файлов, которое может поместиться в командной строке. На очень большом дереве это может иметь большое значение.
Дэвид Пашли
1
Кроме того, print0 / xargs -0 будет обрабатывать даже очень странные имена файлов; не так уверен насчет find -exec.
Слеське
8

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

# chmod -R . u=rwX,g=rX,o=rX

Магия - это разрешение X, а не x. Страница chmod описывает это так:

выполнять / искать, только если файл является каталогом или уже имеет разрешение на выполнение для некоторого пользователя

Это не подходит в вашем случае, так как ваши файлы имеют разрешение на выполнение, поэтому будут соответствовать второму тесту.

Дэвид Пашли
источник
1
g должен быть rwX для 775 и 664.
Авантюрин
1

Я сделал скрипт из решения freiheit, он добавляет базовую проверку аргументов.

#!/bin/sh

if [ $# -lt 1 ]; then
    echo "USAGE: $0 <path>"
    exit 1
fi

find $1 -type d -print0 | xargs -0 chmod 0755
find $1 -type f -print0 | xargs -0 chmod 0644
Marcs
источник
Отличная идея. Тем не менее, вторая линия выдает ошибку , когда цель является каталогом: chmod: missing operand after ‘0644’. Могу ли я предложить обернуть операторы find проверкой, чтобы увидеть, существует ли цель? if [ -d $1 ]; then find $1 -type d -print0 | xargs -0 chmod 0755; fi; if [ -f $1 ]; then find $1 -type f -print0 | xargs -0 chmod 0644; fi
Underverse
Это почти правильно; но если целью является каталог, вы забыли chmod файлы в нем, и если это файл, вам просто нужно только chmod этот файл.
Sean
0

В случае, если вы используете ssh, рекомендуется не изменять ~/.sshразрешения.

DIR=/home/user
find $DIR -type d -not -path "$DIR/.ssh" -print0 | xargs -0 chmod 0775
find $DIR -type f -not -path "$DIR/.ssh/*" -print0 | xargs -0 chmod 0664
Tombart
источник
0

На днях я сделал очень простой bash-скрипт, потому что мне нужно было исправить разрешения. Почему не существует формальной утилиты для сброса основных, не-root, прав доступа к файлам и папкам?

Скрипт использует find для 755 всех папок и 644 библиотек. Затем он проверяет каждый файл с помощью readelf, чтобы увидеть, имеет ли он двоичный заголовок elf. Если нет, он сканирует первые два символа для Шебанга #!. Он проверяет 755 этих экземпляров и 644 все остальное после того, как проверяет, есть ли у файла уже соответствующее разрешение.

Особые случаи обрабатываются с исключением, например, *.bakдля игнорируемых файлов.

#!/bin/bash
read -r -p "Correct file and folder permissions? [y/N] " chse
if [[ "$chse" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
  echo "Processing ..."
  find -H $(pwd) -type d -exec chmod 0755 {} \;
  # set dirs to 755
  find -H $(pwd) -type f \( -iname '*.so.*' -o -iname '*.so' \) -exec chmod 0644 {} \;
  # libs
  IFS=$'\n'
  for value in $(find -H $(pwd) -type f ! \( -iname '*.so.*' -o -iname '*.so' -o -iname '*.bak' \) -printf '%p\n'); do
    tstbin=$(readelf -l "$value" 2>/dev/null | grep -Pio 'executable|shared')
    if [ -z "$tstbin" ]; then
      tstbat=$(cat "$value" | head -c2 | grep -io '#!')
      if [ -n "$tstbat" ]; then
        perm=$(stat -c '%a' "$value")
        if [ "$perm" != "755" ]; then
          chmod 755 $value
          echo "Set script  755 $value"
          # set batch to 755
        fi
      else
        perm=$(stat -c '%a' "$value")
        if [ "$perm" != "644" ]; then
          chmod 644 $value
          echo "Set regular 644 $value"
          # set regular files to 644
        fi
      fi
      # above aren't elf binary
    else
      perm=$(stat -c '%a' "$value")
      if [ "$perm" != "755" ]; then
        chmod 755 $value
        echo "Set binary  755 $value"
        # set elf binaries to 755
      fi
    fi
  done
  unset IFS
  # process linux permissions for files and folders
else
  echo "Aborted."
fi
noabody
источник
0

Я нашел упрощенное решение C-shell. Это может быть не полностью надежным доказательством, но должно работать для большинства каталогов. Предполагается, что команда Unix 'file' работает, и находит exec-файлы для сброса их обратно в exec-разрешения:

find /home/user -type d | xargs chmod 0775
find /home/user -type f | xargs -0 chmod 0664
find /home/user -type f -exec file {} \; | grep executable | cut -d":" -f1 | xargs chmod 0775
К. Донован
источник
1
Это не просто повторяет некоторые ответы, но и приводит к ошибке и функциональности, которые ОП не запрашивал.
Ральф Фридл
0

Альтернатива, которая точно не отвечает первоначальному запросу, но более вероятно, что подразумевает OP, состоит в том, чтобы указать разрешения символически. Например, я предполагаю, что OP хочет «удалить публичный доступ на запись и удалить разрешение на выполнение из всех файлов».

Это возможно, если вы используете символическое разрешение.

  • ow это "удалить доступ на запись из общего доступа" ("o" - другие, "-" - удалить, "w" - написать)
  • топор - «удалить выполнение для всех только для файлов» («a» - все, «-» - удалить, «x» - выполнить)

Записывая его таким образом, вместо того, чтобы явно устанавливать «0664», вы избегаете случайного разрешения дополнительных разрешений для файлов, которые были ранее заблокированы. Например, если файл был 0770, он не станет 0664 по ошибке.

Для выполнения первого требования вы можете просто использовать chmod:

chmod --recursive o-w $dir

Для выполнения второго требования:

find $dir -type f -exec chmod a-x {} +

Или сделать оба:

find $dir -type f -exec chmod a-x,o-w {} +
find $dir -type d -exec chmod o-w {} +
chutz
источник