Совет от @ gniourf_gniourf за прояснение фундаментального заблуждения.
В этом ответе делается попытка дать обзор существующих ответов и обсудить их тонкости и относительные достоинства, а также предоставить справочную информацию , особенно в отношении переносимости .
Поиск исполняемых файлов может относиться к двум различным вариантам использования :
- ориентированный на пользователя : поиск файлов, которые может исполнять текущий пользователь .
- файлово-ориентированный : поиск файлов, для которых установлены (один или несколько) битов разрешения на выполнение .
Обратите внимание, что в любом сценарии может иметь смысл использоватьfind -L ...
вместо find ...
того, чтобы также найти символические ссылки на исполняемые файлы .
Обратите внимание, что в простейшем случае, ориентированном на файлы, - поиск исполняемых файлов с битом разрешений на выполнение, установленным для ВСЕХ трех участников безопасности (пользователь, группа, другие) - обычно , но не обязательно, дает те же результаты, что и в сценарии, ориентированном на пользователя - и это важно понимать разницу.
Ориентация на пользователя ( -executable
)
Общепринятый ответ похвально рекомендует -executable
, ЕСЛИ GNU find
доступен.
- GNU
find
поставляется с большинством дистрибутивов
Linux
- Напротив, платформы на основе BSD, включая macOS, поставляются с функцией поиска BSD, которая менее эффективна.
- В соответствии с требованиями сценария,
-executable
сопоставляются только файлы, которые может выполнять текущий пользователь (есть крайние случаи. [1] ).
BSD find
альтернатива предлагает общепринятом ответ ( -perm +111
) отвечает на другой , файл заточенный вопрос (как и сам ответ состояние).
- Использование только
-perm
для ответа на пользователь заточенный вопроса является невозможным , потому что нужно, чтобы связать в файл пользователей и групп идентичность с текущим пользователем , в то время как -perm
можно только проверить в файл разрешение.
Используя только функции POSIXfind
, на вопрос нельзя ответить без привлечения внешних утилит.
Таким образом, лучшие -perm
может сделать (сам по себе) является приближением из -executable
. Возможно, это более точное приближение, чем -perm +111
есть-perm -111
, чтобы найти файлы, в которых бит исполняемого файла установлен для ВСЕХ участников безопасности (пользователя, группы, других) - это кажется мне типичным сценарием реального мира. В качестве бонуса он также является POSIX-совместимым (используйте find -L
для включения символических ссылок, см. Ниже для объяснения):
find . -type f -perm -111 # or: find . -type f -perm -a=x
Ответ gniourf_gniourf представляет собой истинный переносимый эквивалент-executable
использования-exec test -x {} \;
, хотя и в ущерб производительности .
Комбинирование -exec test -x {} \;
с -perm +111
(т. Е. Файлы с хотя бы одним установленным исполняемым битом) может улучшить производительность, поскольку exec
нет необходимости вызывать его для каждого файла (ниже используется POSIX-совместимый эквивалент поиска BSD -perm +111
/ GNU find -perm /111
; см. Объяснение ниже) :
find . -type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \) -exec test -x {} \; -print
Файлово-ориентированный ( -perm
)
- Для того, чтобы ответить на файл заточенные вопросы , то есть достаточно использовать POSIX-совместимый
-perm
первичный (известный как тест в терминологии находит GNU).
-perm
позволяет вам проверять любые права доступа к файлам, а не только исполняемость.
- Разрешения указываются в восьмеричном или символьном режиме . Восьмеричные режимы - это восьмеричные числа (например,
111
), тогда как символьные режимы - это строки (например, a=x
).
- Символьные режимы идентифицируют участников безопасности как
u
(пользователь), g
(группа) и o
(другие) или a
относятся ко всем трем. Разрешения выражаются как x
, например, для исполняемого файла и назначаются принципалам с помощью операторов =
, +
и -
; для полного обсуждения, включая восьмеричные режимы, см. спецификацию POSIX для chmod
утилиты .
- В контексте
find
:
- Префикс режима с помощью
-
(например, -ug=x
) означает: сопоставление файлов со всеми указанными разрешениями (но соответствующие файлы могут иметь дополнительные разрешения).
- Наличие без префикса (например
755
) означает: матч файлы , которые имеют этот полный, точный набор разрешений.
- Предостережение : как GNU find, так и BSD find реализуют дополнительный нестандартный префикс с логикой набора битов-ЛЮБОГО-из-указанного-разрешения , но делают это с несовместимым синтаксисом :
- BSD находит:
+
- Находка GNU:
/
[2]
- Поэтому избегайте этих расширений, если ваш код должен быть переносимым .
- Приведенные ниже примеры демонстрируют переносимые ответы на различные вопросы, связанные с файлами.
Примеры команд, ориентированных на файлы
Примечание:
- Следующие примеры являются POSIX-совместимыми , то есть они должны работать в любой POSIX-совместимой реализации, включая GNU find и BSD find; в частности, это требует:
- НЕ использовать нестандартные префиксы режима
+
или /
.
- Использование форм POSIX первичных логических операторов :
!
для НЕ (GNU find и BSD find также позволяют -not
); обратите внимание, что \!
используется в примерах для защиты !
от расширений истории оболочки
-a
для И (поиск GNU и поиск BSD также позволяют -and
)
-o
для OR (GNU find и BSD find также позволяют -or
)
- В примерах используются символические режимы, поскольку их легче читать и запоминать.
- С приставкой режиме
-
, то =
и +
операторы могут быть взаимозаменяемыми (например, -u=x
эквивалентно -u+x
- если вы не применять -x
позже, но нет никакого смысла делать это).
- Используйте
,
для присоединения к частичным режимам; Подразумевается логика И; например, -u=x,g=x
означает, что должны быть установлены и пользовательский, и групповой исполняемый бит.
- Сами режимы не могут выражать отрицательное совпадение в смысле «совпадение, только если этот бит НЕ установлен»; Вы должны использовать отдельное
-perm
выражение с НЕ первичным, !
.
- Обратите внимание , что ФАЙНД праймериз (такие как
-print
, или -perm
; также известный как действия и тесты в GNU находке) являются неявно соединены с -a
(логическое И), и что -o
и , возможно , круглые скобки (сбежавших , как \(
и \)
для оболочки) необходимы для реализации или логики.
find -L ...
вместо просто find ...
используется для сопоставления символических ссылок с исполняемыми
файлами
-L
указывает find для оценки целей символических ссылок вместо самих символических ссылок; Таким образом, без -L
, -type f
будет игнорировать символические ссылки в целом.
# Match files that have ALL executable bits set - for ALL 3 security
# principals (u (user), g (group), o (others)) and are therefore executable
# by *anyone*.
# This is the typical case, and applies to executables in _system_ locations
# (e.g., /bin) and user-installed executables in _shared_ locations
# (e.g., /usr/local/bin), for instance.
find -L . -type f -perm -a=x # -a=x is the same as -ugo=x
# The POSIX-compliant equivalent of `-perm +111` from the accepted answer:
# Match files that have ANY executable bit set.
# Note the need to group the permission tests using parentheses.
find -L . -type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \)
# A somewhat contrived example to demonstrate the use of a multi-principial
# mode (comma-separated clauses) and negation:
# Match files that have _both_ the user and group executable bit set, while
# also _not_ having the other executable bit set.
find -L . -type f -perm -u=x,g=x \! -perm -o=x
[1] Описание -executable
от man find
GNU find 4.4.2:
Соответствует исполняемым файлам и каталогам, доступным для поиска (в смысле разрешения имен файлов). При этом учитываются списки управления доступом и другие артефакты разрешений, которые игнорируются тестом -perm. В этом тесте используется системный вызов access (2), поэтому серверы NFS могут обмануть его, выполняя сопоставление UID (или подавление корневого идентификатора), поскольку многие системы реализуют доступ (2) в ядре клиента и поэтому не могут использовать информация об отображении UID, хранящаяся на сервере. Поскольку этот тест основан только на результате системного вызова access (2), нет никакой гарантии, что файл, для которого этот тест прошел успешно, действительно может быть выполнен.
[2] GNU find версии старше 4.5.12 также разрешили префикс +
, но он был сначала объявлен устаревшим и в конечном итоге удален, потому что комбинирование +
с символьными режимами дает, вероятно, неожиданные результаты из-за того, что оно интерпретируется как точная маска разрешений. Если вы (а) используете версию до 4.5.12 и (б) ограничиваете себя восьмеричным числом режимов только, вы могли бы уйти с использованием +
с как GNU найти и BSD найти, но это не очень хорошая идея.