Unix find: поиск исполняемых файлов
Какой тип параметра/флаг можно использовать с командой Unix find
, чтобы я искал исполняемые файлы?
Ответы
Ответ 1
В версиях GNU find вы можете использовать -executable
:
find . -type f -executable -print
Для версий поиска BSD вы можете использовать -perm
с +
и восьмеричную маску:
find . -type f -perm +111 -print
В этом контексте "+" означает "любой из этих битов установлен", а 111 - биты выполнения.
Обратите внимание, что это не совпадает с предикатом -executable
в поиске GNU. В частности, -executable
проверяет, что файл может быть выполнен текущим пользователем, а -perm +111
просто проверяет, установлены ли разрешения на выполнение.
Более старые версии GNU find также поддерживают синтаксис -perm +111
, но с 4.5.12 этот синтаксис больше не поддерживается. Вместо этого вы можете использовать -perm /111
, чтобы получить это поведение.
Ответ 2
Совет шляпы @gniourf_gniourf для устранения фундаментального заблуждения.
Этот ответ пытается предоставить обзор существующих ответов и обсудить их тонкости и относительные достоинства, а также обеспечить справочная информация, особенно в отношении переносимости.
Поиск исполняемых файлов может относиться к двум различным вариантам использования:
- ориентированный на пользователя: найдите файлы, которые исполняются текущим пользователем.
- file-centric: найдите файлы, у которых есть (один или несколько) исполняемых разрешений бит.
Обратите внимание, что в любом случае может быть смысл использовать find -L ...
вместо find ...
, чтобы также находить символические ссылки на исполняемые файлы.
Обратите внимание, что простейший файлоцентрический случай - поиск исполняемых файлов с битом исполняемых разрешений, установленным для ВСЕХ трех участников безопасности (пользователя, группы, другого) - обычно будет, но не обязательно даст те же результаты, что и сценарий, ориентированный на пользователя - и важно понять разницу.
Пользовательский (-executable
)
-
принятый ответ похвально рекомендует -executable
, если доступен GNU find
.
- GNU
find
поставляется с большинством дистрибутивов Linux
- В отличие от BSD-основанных платформ, включая OSX, есть поиск BSD, который менее эффективен.
- Как требует сценарий,
-executable
соответствует только файлам, которые может выполнить текущий пользователь (есть случаи краев. [1]).
-
Альтернатива BSD find
, предлагаемая принятым ответом (-perm +111
) , отвечает на другой, ориентированный на файл вопрос (поскольку сам ответ утверждает).
- Использовать только
-perm
для ответа на пользовательский вопрос невозможно, потому что необходимо связать идентификатор пользователя и группы файла с текущим пользователем, тогда как -perm
может только тестировать разрешения файла.
Используя только функции POSIX find
, на вопрос нельзя ответить без привлечения внешних утилит.
-
Таким образом, лучший -perm
может (само по себе) является приближением of -executable
. Возможно, более близкое приближение, чем -perm +111
, есть -perm -111
, чтобы найти файлы, у которых есть исполняемый бит, установленный для ВСЕХ участников безопасности (пользователя, группы, другой) - это наводит меня как типичный реальный - мирный сценарий. В качестве бонуса он также совместим с POSIX (используйте find -L
для включения символических ссылок, см. Ниже для объяснения):
find . -type f -perm -111 # or: find . -type f -perm -a=x
-
gniourf_gniourf answer предоставляет истинный переносимый эквивалент -executable
, используя -exec test -x {} \;
, хотя за счет производительности.
-
Объединение -exec test -x {} \;
с -perm +111
(т.е. файлы с хотя бы одним исполняемым битовым набором) может помочь производительности в том, что exec
не нужно вызывать для каждого файла (ниже используется POSIX-совместимый эквивалент BSD find -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 find termology).
-
-perm
позволяет вам проверять любые разрешения на доступ к файлам, а не только выполнимость.
- Разрешения указаны как восьмеричные или символические режимы. Восьмеричные режимы представляют собой восьмеричные числа (например,
111
), тогда как символические режимы являются строками (например, a=x
).
- Символьные режимы идентифицируют участников безопасности как
u
(пользователь), g
(группа) и o
(другие), или a
для обозначения всех трех. Разрешения выражаются как x
для исполняемого файла, например, и назначаются принципалам с использованием операторов =
, +
и -
; для полного обсуждения, включая восьмеричные режимы, см. спецификацию POSIX для утилиты chmod
.
- В контексте
find
:
- Префикс режима с
-
(например, -ug=x
) означает: сопоставлять файлы, имеющие все указанные разрешения (но соответствующие файлы могут иметь дополнительные разрешения).
- Наличие префикса НЕТ(например,
755
) означает: файлы соответствия, которые имеют полный и точный набор разрешений.
- Caveat: Поиск GNU и поиск BSD реализуют дополнительный, нестандартный префикс с - это ЛЮБОЙ из- логика с установленными разрешениями-бит-бит, но сделать это с помощью несовместимого синтаксиса:
- BSD find:
+
- Поиск GNU:
/
[2]
- Поэтому избегать этих расширений, если ваш код должен быть переносимым.
Нижеприведенные примеры демонстрируют переносные ответы на различные вопросы, связанные с файлами.
Примеры команд с файловой системой
Примечание:
- Следующие примеры соответствуют POSIX, что означает, что они должны работать в любой совместимой с POSIX реализации, включая поиск GNU и поиск BSD; в частности, это требует:
- НЕ использовать префиксы нестандартного режима
+
или /
.
- Использование форм POSIX логических операторов:
-
!
для NOT (поиск GNU и поиск BSD также позволяют -not
); обратите внимание, что \!
используется в примерах, чтобы защитить !
от расширений истории оболочки
-
-a
для AND (поиск GNU и поиск BSD также позволяют -and
)
-
-o
для OR (поиск GNU и поиск BSD также позволяют -or
)
- В примерах используются символические режимы, потому что их легче читать и запоминать.
- С префиксом режима
-
операторы =
и +
могут использоваться взаимозаменяемо
(например, -u=x
эквивалентно -u+x
- если вы не примените -x
позже, но там нечего делать).
- Используйте
,
для присоединения к частичным режимам; И логика подразумевается; например, -u=x,g=x
означает, что должны быть установлены как пользовательский, так и исполняемый бит группы.
- Режимы сами не могут выразить отрицательное соответствие в смысле "матч, только если этот бит НЕ установлен"; вы должны использовать отдельное выражение
-perm
с НЕ первичным, !
.
- Обратите внимание, что найти первичные элементы (такие как
-print
или -perm
, также известные как действия и тесты в поиске GNU) неявно соединены с -a
(логическим И) и что -o
и, возможно, круглые скобки ( экранированные как \(
и \)
для оболочки) необходимы для реализации логики ИЛИ.
-
find -L ...
вместо find ...
используется для сопоставления символических ссылок с исполняемыми файлами
-
-L
инструктирует найти для оценки целей символических ссылок вместо самих символических ссылок; поэтому без -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:
Соответствует исполняемым файлам и каталогам, которые доступны для поиска (в смысле разрешения имени файла). Это учитывает доступ контрольных списков и других разрешений артефактов, которые игнорирует тест -mm. Этот тест использует системный вызов доступа (2), и поэтому может быть обманутых серверами NFS, которые выполняют сопоставление UID (или root-squashing), поскольку многие системы реализуют доступ (2) в ядре клиента и поэтому не могут используйте информацию отображения UID, хранящуюся на сервере. Поскольку этот тест основан только на результате системного вызова доступа (2), там не гарантирует, что файл, для которого этот тест успешно завершен, может быть выполнен.
[2] GNU найти версии старше 4.5.12 также допускает префикс +
, но это было сначала устарело и в конечном итоге удалено, потому что объединение +
с символическими режимами дает вероятные результаты, которые дают неожиданные результаты из-за интерпретации в качестве точной маски разрешений. Если вы (а) запускаете версию до версии 4.5.12 и (б) ограничиваете себя только восьмеричными режимами, вы можете избежать использования +
с помощью поиска GNU и поиска BSD, но это не очень хорошая идея.
Ответ 3
Вы можете использовать флаг проверки -executable
:
-executable
Matches files which are executable and directories which are
searchable (in a file name resolution sense).
Ответ 4
Чтобы иметь еще одну возможность 1 найти файлы, которые исполняются текущим пользователем:
find . -type f -exec test -x {} \; -print
(здесь приведена тестовая команда, найденная в PATH, скорее всего, /usr/bin/test
, а не встроенная).
1 Используйте это только в том случае, если флаг -executable
find
недоступен! это существенно отличается от решения -perm +111
.
Ответ 5
Это сработало для меня и подумало о совместном использовании...
find ./ -type f -name "*" -not -name "*.o" -exec sh -c '
case "$(head -n 1 "$1")" in
?ELF*) exit 0;;
MZ*) exit 0;;
#!*/ocamlrun*)exit0;;
esac
exit 1
' sh {} \; -print
Ответ 6
find . -executable -type f
на самом деле не гарантирует, что файл является исполняемым, он найдет файлы с установленным битом выполнения. Если вы делаете
chmod a+x image.jpg
приведенная выше находка будет думать, что image.jpg является исполняемым файлом, даже если это действительно jpeg-образ с установленным битом выполнения.
Обычно я общаюсь с этим вопросом:
find . -type f -executable -exec file {} \; | grep -wE "executable|shared object|ELF|script|a\.out|ASCII text"
Если вы хотите, чтобы находка действительно печатала информацию о купе с исполняемыми файлами, вы можете сделать что-то вроде этого:
find . -type f -executable -printf "%i.%D %s %m %U %G %[email protected] %p" 2>/dev/null |while read LINE
do
NAME=$(awk '{print $NF}' <<< $LINE)
file -b $NAME |grep -qEw "executable|shared object|ELF|script|a\.out|ASCII text" && echo $LINE
done
В приведенном выше примере полный путь к файлу находится в последнем поле и должен отражать, где вы его ищете, с awk "NAME= $(awk '{print $NF}' < < $LINE)"
если имя файла было в другом месте в строке вывода find, вам нужно заменить "NF" на правильную цифровую позицию. Если ваш разделитель не является пространством, вам также нужно указать awk, что ваш разделитель.
Ответ 7
Это смешно, что это не супер-легко... не говоря уже о невозможности. Руки вверх, я откладываю на Apple/Spotlight...
mdfind 'kMDItemContentType=public.unix-executable'
По крайней мере, он работает!
Ответ 8
Хорошим ответом будет: "ваши исполняемые файлы находятся в каталогах, содержащихся в вашей переменной PATH", но это на самом деле не нашло бы ваших исполняемых файлов и могло бы пропустить много исполняемых файлов в любом случае.
Я мало что знаю о mac, но я думаю, что "mdfind" kMDItemContentType = public.unix-executable "может пропустить такие вещи, как интерпретируемые скрипты
Если вам удобно находить файлы с установленными исполняемыми битами (независимо от того, являются ли они фактически исполняемыми), то это нормально делать
find . -type f -perm +111 -print
где поддерживается опция "-executable", будет добавлен еще один фильтр, смотрящий на acl и другие артефакты разрешений, но технически не сильно отличающийся от "-pemr +111".
Возможно, в будущем find будет поддерживать "-magic" и позволит вам явно искать файлы с определенным идентификатором магии... но тогда вы бы haveto указать, чтобы удалить все исполняемые форматы магии id.
Я не знаю технически правильного легкого выхода на unix.
Ответ 9
У меня была одна и та же проблема, и ответ был в исходном коде dmenu: утилита установки, созданная для этой цели. Вы можете скомпилировать файлы 'stest.c' и 'arg.h', и они должны работать. Для использования есть справочная страница, которую я поставил для удобства:
STEST(1) General Commands Manual STEST(1)
NAME
stest - filter a list of files by properties
SYNOPSIS
stest [-abcdefghlpqrsuwx] [-n file] [-o file]
[file...]
DESCRIPTION
stest takes a list of files and filters by the
files' properties, analogous to test(1). Files
which pass all tests are printed to stdout. If no
files are given, stest reads files from stdin.
OPTIONS
-a Test hidden files.
-b Test that files are block specials.
-c Test that files are character specials.
-d Test that files are directories.
-e Test that files exist.
-f Test that files are regular files.
-g Test that files have their set-group-ID
flag set.
-h Test that files are symbolic links.
-l Test the contents of a directory given as
an argument.
-n file
Test that files are newer than file.
-o file
Test that files are older than file.
-p Test that files are named pipes.
-q No files are printed, only the exit status
is returned.
-r Test that files are readable.
-s Test that files are not empty.
-u Test that files have their set-user-ID flag
set.
-v Invert the sense of tests, only failing
files pass.
-w Test that files are writable.
-x Test that files are executable.
EXIT STATUS
0 At least one file passed all tests.
1 No files passed all tests.
2 An error occurred.
SEE ALSO
dmenu(1), test(1)
dmenu-4.6 STEST(1)