Как проверить, является ли файл исполняемым, его владелец ** не обязательно я **

Это не дублирующий вопрос.

Предположим, у меня есть

  1. полный путь
  2. в обычный файл с именем target
  3. который может принадлежать какому-то другому пользователю.
  4. и среда может быть урезана (busybox с очень небольшим включением)

В сценарии оболочки, как я могу проверить, является ли этот файл исполняемым его владельцем, если я не могу быть его владельцем? Представьте, что цель моей программы — проверить, все ли хорошо настроен для запуска других вещей (поскольку среда могла быть разрушена другими пользователями), и он ищет в определенном каталоге, чтобы убедиться, что владельцы каждого файла имеют разрешение на выполнение своего файла.

Это профессиональный контекст, а не домашнее задание.

Любое решение, которое я буду использовать, должно охватывать все виды старых сред Linux, в настройке которых я не участвовал (поэтому в них могут быть отсутствующие вещи, которые вы обычно ожидаете, такие как which или некоторые параметры find и т. д.) .

Однако этот вопрос может быть полезен для тех, кто не сталкивается с этим ограничением, поэтому я ценю другие решения, требующие более полных или современных сред.

[ -x "$path" ] только сообщает мне, могу ли я его выполнить.

ls -l "$path" и проверка, является ли четвертый символ x, кажется слишком хрупкой: -rwxrw-rw- 1 otheruser group 26 Jun 13 10:57 target

ls -F "$path" и проверить, заканчивается ли оно на *, кажется немного лучше: target* Одна среда, которую я тестировал, действительно учитывает, кто является фактическим владельцем... Но это не кажется лучшим способом...


person user1011471    schedule 13.06.2018    source источник
comment
Что делать, если fs смонтирован noexec? Это предотвратит выполнение пользователем файла независимо от его разрешений.   -  person that other guy    schedule 13.06.2018
comment
Я отредактировал, чтобы было ясно, что это не дубликат ни одного из них. (Я думаю, причина, по которой я исключил [ -x "$path" ], была технически достаточной, чтобы отличить) Моя программа является валидатором, и она хочет убедиться, что владелец каждого файла в каталоге может выполняться этим конкретным владельцем. Я не думаю, что группы учитываются, потому что я удалил пользовательские разрешения на то, что мне принадлежало, у которого была (моя) группа и другой набор x, и я не мог это выполнить. Не домашнее задание. Должен быть надежным и справляться со всеми видами странных/старых сред Linux.   -  person user1011471    schedule 14.06.2018


Ответы (3)


permissions=$(stat -c "%a" target)
permissions=$(( ${permissions: -3: 1} % 2 ))

stat дает вам права доступа к файлам в восьмеричном формате. Затем нам нужен только символ для разрешений владельца (технически третий справа, а не первый символ), а затем нужно проверить, не является ли он нечетным (исполняемый в восьмеричном формате - это 1 бит).

Если разрешения равны 1, он выполняется владельцем. Если это 0, это не так.

Вместо этого в более старых средах могут потребоваться арифметические выражения:

permissions=$(stat -c "%a" $target)
if [ $((0$permissions & 0100)) -ne 0 ]; then
    # executable by owner
else
    # not executable by owner
fi
person jeremysprofile    schedule 13.06.2018
comment
@thatotherguy, это берет подстроку val, начинающуюся с 3 символов с правого конца? Если да, то не является ли следующий аргумент длиной и должен ли он быть 1 вместо -2? Или... в чем я ошибаюсь, когда дело доходит до этого -2? - person user1011471; 14.06.2018
comment
@ user1011471, вы можете попробовать протестировать код самостоятельно и убедиться, что он работает. - person jeremysprofile; 14.06.2018
comment
@user1011471 wiki.bash-hackers.org/syntax/pe#negative_length_value - person jeremysprofile; 15.06.2018
comment
Ой. Это работает, начиная с Bash 4.2-alpha. В одном из моих более поздних правок к OP я упоминаю о необходимости поддержки некоторых сумасшедших старых сред, и в этом случае 1 было бы лучше, верно? - person user1011471; 15.06.2018
comment
@ user1011471, да. Я считаю, что отрицательное смещение может не работать даже в достаточно старых версиях bash (но я могу ошибаться, я не смог найти источник, подтверждающий это чувство) - person jeremysprofile; 15.06.2018
comment
Если вы добавите 1 в качестве альтернативы, которая работает на старых машинах, я приму этот ответ. Это то, что я в итоге использовал. - person user1011471; 15.06.2018
comment
@ user1011471, изменено. 1 является правильным в любом случае, поэтому он не должен быть альтернативой. - person jeremysprofile; 15.06.2018
comment
Другой альтернативой может быть if (( 0$val & 0100)); then echo "executable by owner"; fi - person that other guy; 15.06.2018

Вы можете использовать find, если не хотите анализировать вывод чего-либо:

if find ${path} -prune -perm -u+x | grep -q ''; then
  echo "Executable by owner"
else
  echo "Not executable by owner"
fi

Параметр -perm позволяет вам проверить, является ли он исполняемым user (владельцем), а параметр -prune предотвращает спуск в каталог, если ${path} является каталогом, поэтому мы можем просто проверить указанный путь сам по себе.

person Brandon Miller    schedule 13.06.2018

ls -l "$path" и проверьте первую группу разрешений (разрешения владельца). Если в нем есть x, то файл является исполняемым его владельцем.

person Athanasios Emmanouilidis    schedule 13.06.2018
comment
Как вы выражаете это (проверка первой группы разрешений на x) в сценарии оболочки? - person user1011471; 13.06.2018