Как проверить групповые разрешения файла

9

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

Вот и все. Просто как тот. Однако:

  1. Мне также нужно, чтобы это было портативно.
  2. test -w <file не скажет мне, можно ли записать группу
  3. Вывод ls -ldполезен для людей, но не уверен в сценариях. Технически я мог бы разобрать вывод, например, drwxrwxr-xчтобы извлечь групповые биты, но это кажется хрупким.
  4. Интерфейс для statполностью несовместим между OS X и другими системами.
  5. find <file> -perm ... не может быть ответом?
mislav
источник
Вам нужно проверить бит разрешения группы или проверить, есть ли у конкретной группы разрешения на запись? Группа (или пользователь) может иметь разрешение на запись через ACL.
Жиль "ТАК - перестань быть злым"
Просто бит разрешения группы. Никакая конкретная группа не имеет отношения.
Мислав

Ответы:

8

Метод № 1 - стат

Вы можете использовать statкоманду, чтобы получить биты прав доступа. statдоступно в большинстве Unixes (OSX, BSD, а не AIX из того, что я могу найти). Это должно работать на большинстве Unixes, кроме OSX и BSD из того, что я могу найти.

$ stat -c "%a" <file>

пример

$ ls -l a
-rw-rw-r-- 1 saml saml 155 Oct  6 14:16 afile.txt

Используйте эту команду:

$ stat -c "%a" afile.txt
664

И используйте простой, grepчтобы увидеть, является ли режим разрешений групп 6 или 7.

$ stat -c "%a" afile.txt | grep ".[67]."

Для OSX и BSD вы должны использовать эту форму stat, stat -f(или , возможно stat -x), и разобрать соответственно. Поскольку параметры statотличаются, вы можете заключить эту команду в lsb_release -aкоманду и вызвать соответствующую версию в зависимости от ОС. Не идеально, но выполнимо. Поймите, что lsb_releaseэто доступно только для дистрибутивов Linux, поэтому нужно будет найти другую альтернативу для тестирования других ОС Unix.

Метод № 2 - найти

Я думаю, что эта команда может служить вам лучше, хотя. Я использую findи printfвыключатель.

пример

$ find a -prune -printf '%m\n'
664

Метод № 3 - Perl

Perl может быть более переносимым способом сделать это в зависимости от ОС, которую вы пытаетесь охватить.

$ perl -le '@pv=stat("afile.txt"); printf "%04o", $pv[2] & 07777;'
0664

ПРИМЕЧАНИЕ . Вышеприведенное использует stat()функцию Perl для запроса битов файловой системы.

Вы можете сделать это более компактным, отказавшись от использования массива @pvи stat()непосредственно работая с выводом :

$ perl -le 'printf "%04o", (stat("a"))[2] & 07777;'
0664
SLM
источник
Я думаю, что вы пропустили его пункт 4. Команда statсильно различается в разных системах и не переносима.
Иордания
@jordanm - спасибо, что видел, искал альтернативу. Я думаю, что find . -printfмогу сделать это, но не могу определить, доступно ли это на OSX 'найти.
SLM
1
Я не смог найти на него ссылки в руководстве POSIX2008, поэтому я склонен согласиться. Я не уверен ни в каких других методах. Я думаю, что вы должны укусить пулю здесь и определить, какая ОС и вызвать апп. Команда, казалось бы, лучший подход.
SLM
1
Я не мог придумать метод, использующий стандартную утилиту оболочки. Вот почему мой ответ использует Perl.
Иордания
1
@jordanm - великие умы. Я тоже работал над решением Perl 8-)
slm
1

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

if perl -e 'use Fcntl ":mode"; exit( ((stat("file.txt"))[2] & S_IWGRP) >> 3)'; then
    echo "file is group writable"
else
    echo "file is not group witeable"
fi

Подобные perlпримеры можно найти в stat perldoc .

jordanm
источник
1

Я закончил lsразбор:

is_group_writable() {
  local ls="$(ls -ld "$1")"
  [ "${ls:5:1}" = "w" ]
}

Я благодарен за обширный ответ @ slm, но ни один из других методов не является таким простым. Этот statметод потребовал бы от меня написания как минимум двух разных вызовов для покрытия OS X, и даже после этого он возвращает восьмеричное представление, к которому мне все еще нужно применить арифметику. Метод Perl в порядке, но требует, чтобы я запустил интерпретатор для такой простой задачи, и я хотел бы сохранить его простым и использовать только утилиты posix.

mislav
источник
2
Вы используете Bash, а не только POSIX. В POSIX:perms=$(ls -ld -- "$1"); perms=${perms%% *}; case $perms in ?????w????) …
Жиль "ТАК - перестань быть злым"
0
FILE="filename";G=$(stat -c '%a' ${FILE} | cut -c2);
if [ $G -gt 5 ];then   echo "Group write is set on ${FILE}";fi

Все стандартные инструменты Unix / Linux.

Я полагаю, что возможно иметь групповую запись, но не групповое чтение. В такой возможности это может быть либо оператор case 2 | 3 | 6 | 7), либо grep '[2 | 3 | 6 | 7]'

доктор
источник