Unix find: wyszukiwanie plików wykonywalnych

Jakiego typu parametru / flagi mogę używać z poleceniem Unix find, aby wyszukiwać pliki wykonywalne?

Author: mklement0, 2010-12-16

9 answers

W wersjach GNU find można użyć -executable:

find . -type f -executable -print

Dla wersji BSD find, możesz użyć -perm z + i maską ósemkową:

find . -type f -perm +111 -print

W tym kontekście " + "oznacza" każdy z tych bitów jest ustawiony", a 111 to bity execute.

Zauważ, że nie jest to identyczne z predykatem -executable w GNU find. W szczególności -executable sprawdza, czy plik może być uruchomiony przez bieżącego użytkownika, natomiast -perm +111 sprawdza, czy ustawione są uprawnienia do wykonywania.

Starsze wersje GNU find wspiera również składnię -perm +111, ale od 4.5.12 Ta składnia nie jest już obsługiwana. Zamiast tego możesz użyć -perm /111, aby uzyskać takie zachowanie.

 135
Author: Laurence Gonsalves,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-18 22:30:43

końcówka kapelusza do @ gniourf_gniourf za Wyjaśnienie podstawowego błędnego przekonania.

Ta odpowiedź stara się dostarczyć przegląd istniejących odpowiedzi i omówić ichsubtelności i względne zalety , a także dostarczyć Informacje ogólne, szczególnie w odniesieniu do przenośności.

Znajdowanie plików wykonywalnych może odnosić się do dwóch odmiennych zastosowań przypadki:

  • user-centric : find files that are executable by the current user.
  • file-centric : Znajdź pliki, które mają (jeden lub więcej) bity uprawnień wykonywalnych ustawione .

Zauważ, że w albo scenariusz może mieć sens użycie find -L ... zamiast find ... w celu znaleźć również dowiązania symboliczne do plików wykonywalnych.

Zauważ, że najprostszy przypadek skoncentrowany na plikach-szukanie plików wykonywalnych z ustawionym bitem uprawnień wykonywalnych dla wszystkich trzech zasad bezpieczeństwa (użytkownik, grupa, inne) - zazwyczaj, ale niekoniecznie daje takie same wyniki jak scenariusz skoncentrowany na użytkowniku-i ważne jest, aby zrozumieć różnicę.

User-centric (-executable)

  • The zaakceptowana odpowiedź godnie poleca -executable, jeśli GNU find na dostępny.

    • GNU find pochodzi z większości dystrybucji Linuksa
        W przeciwieństwie do tego, platformy oparte na BSD, w tym macOS, są dostarczane z BSD find, który jest mniej wydajny.
  • zgodnie ze scenariuszem, -executabledopasowuje tylko pliki, które może wykonać bieżący użytkownik (istnieją przypadki brzegowe.[1]).
  • The BSD find alternatywa oferowana przez zaakceptowaną odpowiedź (-perm +111) odpowiedzi a różne, plik - pytanie centryczne (jak sama odpowiedź stwierdza).

    • użycie tylko -perm aby odpowiedzieć użytkownikowi - pytanie jest niemożliwe, ponieważ potrzebne jest powiązanie tożsamości użytkownika pliku i grupy z bieżącego użytkownika , podczas gdy -perm może przetestować tylko uprawnienia pliku .
      Using only POSIX find funkcje , na pytanie nie można odpowiedzieć bez udziału zewnętrznych narzędzi.
    • Tak więc, najlepsze -perm może zrobić (sam) jest przybliżenie z dnia -executable. być może bliżej niż -perm +111 jest -perm -111, aby znaleźć pliki, które mają bit wykonywalny ustawiony dla wszystkich zasad bezpieczeństwa (użytkownik, grupa, Inne) - to wydaje mi się typowym scenariuszem rzeczywistym. Jako bonus, zdarza się również, że jest zgodny z POSIX (użycie find -L aby dołączyć dowiązania symboliczne, zobacz dalej poniżej Wyjaśnienie):

      find . -type f -perm -111  # or: find . -type f -perm -a=x
      
  • Gniourf_gniourf ' s answer Zapewnia prawdziwy, przenośny odpowiednik -executable, używając -exec test -x {} \;, aczkolwiek kosztem wydajności .

    • łączenie -exec test -x {} \; z -perm +111 (tj. pliki z co najmniej jednym zestawem bitów wykonywalnych mogą pomóc w wydajności, ponieważ exec nie muszą być wywoływane dla każdy plik (poniższy plik używa zgodnego z POSIX odpowiednika BSD find -perm +111 / GNU find -perm /111; więcej informacji znajdziesz poniżej):

      find . -type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \) -exec test -x {} \; -print
      
  • File-centric (-perm)

    • to answer file - centric questions , it is wystarczy użyć zgodnego ze standardem POSIX -perm primary (znanego jako test w terminologii GNU find).
      • -perm pozwala na przetestowanie dowolne uprawnienia do plików, nie tylko wykonywalność.
      • uprawnienia są określone jako ósemkowe lub tryby symboliczne . Tryby ósemkowe to liczby ósemkowe (np. 111), podczas gdy tryby symboliczne to ciągi znaków (np. a=x).
      • tryby symboliczne identyfikują zasady bezpieczeństwa jako u (użytkownik), g (Grupa) I o (inne) lub a W odniesieniu do wszystkich trzech. Uprawnienia są wyrażane na przykład jako x dla pliku wykonywalnego i przypisywane do zleceniodawcy korzystający z operatorów =, + I -; dla pełnej dyskusji, w tym trybów ósemkowych, zobacz specyfikację POSIX dla chmod narzędzia.
      • w kontekście find:
        • prefiks trybu z - (na przykład, -ug=x) oznacza: dopasuj pliki, które mają wszystkie uprawnienia określone (ale dopasowane pliki mogą mieć dodatkowe uprawnienia).
        • posiadanie bez prefiksu (np. 755) oznacza: dopasowanie pliki, które mają ten pełny, dokładny zestaw uprawnień.
        • Caveat : zarówno GNU find I BSD find implementują dodatkowy, Niestandardowy prefiks z są-dowolnymi-z-podanych-praw-bitów-ustawionych logiki , ale czynią to z niezgodna składnia :
          • BSD find: +
          • GNU find: / [2]
        • dlatego unikaj tych rozszerzeń, jeśli Twój kod musi być przenośny.
    • poniższe przykłady pokazują przenośne odpowiedzi na różne pytania związane z plikami.

    Przykłady poleceń zorientowanych na plik

    Uwaga:

    • poniższe przykładysą zgodne z POSIX , co oznacza, że powinny działać w dowolnej implementacji zgodnej z POSIX, w tym GNU find I BSD find; w szczególności wymaga to:
      • nie używać niestandardowe prefiksy trybu + lub /.
      • używanie form POSIX z logicznych operatorów podstawowych :
        • ! for NOT (GNU find I BSD find pozwalają również -not); zauważ, że \! jest używany w przykładach, aby chronić ! przed rozszerzeniami historii powłoki
        • -a for AND (GNU find I BSD find również pozwalają -and)
        • -o for OR (GNU find I BSD find również pozwalają -or)
    • The przykłady wykorzystują tryby symboliczne , ponieważ są łatwiejsze do odczytania i zapamiętania.
      • z prefiksem mode - operatory = i + mogą być używane zamiennie (np. {[60] } jest równoważne -u+x - chyba że zastosujesz -x później, ale nie ma sensu tego robić).
      • użyj , do łączenia trybów częściowych; logika jest domyślna; np. -u=x,g=x oznacza, że zarówno użytkownik , jak i musi być ustawiony bit wykonywalny grupy.
      • Tryby nie mogą same wyrażają ujemne dopasowanie w sensie "dopasuj tylko jeśli ten bit nie jest ustawiony"; musisz użyć oddzielnego -perm wyrażenia z NOT primary, !.
    • zauważ, że podstawowe wartości find (takie jak -print, lub -perm; znane również jako akcje i testy W GNU find) są w domyśle połączone z -a (logiczne i), i że -o i ewentualnie nawiasy \( i \) dla powłoki) są potrzebne do wdrożenia lub logiki.
    • find -L ... zamiast tylko find ... jest używany w celu dopasowania dowiązań symbolicznych do plików wykonywalnych
      • -L nakazuje find ocenić cele dowiązań symbolicznych zamiast samych dowiązań symbolicznych; dlatego bez -L, -type f całkowicie zignorowałby dowiązania symboliczne.
    # 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] Opis -executable z man find jako GNU find 4.4.2:

    Mecze pliki wykonywalne i katalogi, które można przeszukiwać (w sensie rozdzielczości nazwy pliku). Uwzględnia to dostęp listy kontrolne i inne artefakty uprawnień, które Test-perm ignoruje. Ten test wykorzystuje wywołanie systemowe access(2), a więc może być oszukany przez serwery NFS, które mapują UID (lub root-squashing), ponieważ wiele systemów implementuje access(2) w jądrze klienta i dlatego nie może wykorzystaj informacje o mapowaniu UID przechowywane na serwerze. Ponieważ test ten opiera się tylko na wyniku wywołania systemowego access(2), nie ma gwarancji, że plik, dla którego test się powiedzie, może zostać rzeczywiście wykonany.

    [2] GNU find wersje starsze niż 4.5.12 również zezwalały na prefiks +, ale najpierw zostało to przestarzałe i ostatecznie usunięte, ponieważ łączenie +Z symboliczne tryby daje prawdopodobnie nieoczekiwane wyniki ze względu na interpretację jako dokładna Maska uprawnień. If you (a) run on a version before 4.5.12 i (b) ogranicz się tylko do ósemkowego, możesz ujść na sucho używając+ Z zarówno GNU find, jak i BSD find, ale to nie jest dobry pomysł.

     25
    Author: mklement0,
    Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
    2018-05-16 13:24:56

    Możesz użyć znacznika testowego -executable:

    -executable
                  Matches files which are executable  and  directories  which  are
                  searchable  (in  a file name resolution sense).
    
     9
    Author: codaddict,
    Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
    2010-12-16 06:44:05

    Aby mieć inną możliwość1 aby znaleźć pliki wykonywalne przez bieżącego użytkownika:

    find . -type f -exec test -x {} \; -print
    

    (Komenda testowa to ta znaleziona w PATH, najprawdopodobniej /usr/bin/test, a nie wbudowana).


    1 Użyj tego tylko wtedy, gdy flaga -executable z find nie jest dostępna! to subtelnie różni się od rozwiązania -perm +111.

     6
    Author: gniourf_gniourf,
    Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
    2014-04-29 12:25:08

    To działało dla mnie i myślałem o dzieleniu się...

    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
    
     2
    Author: AjayKumarBasuthkar,
    Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
    2013-11-28 06:49:43
    find . -executable -type f
    

    Tak naprawdę nie gwarantuje, że plik jest wykonywalny. If you do

    chmod a+x image.jpg
    

    Powyższe znalezisko będzie myśleć obraz.jpg jest programem wykonywalnym, nawet jeśli tak naprawdę jest to obraz jpeg z ustawionym bitem wykonania.

    Ogólnie pracuję wokół problemu z tym:

    find . -type f -executable -exec file {} \; | grep -wE "executable|shared object|ELF|script|a\.out|ASCII text"
    

    Jeśli chcesz, aby find rzeczywiście wydrukował informacje o plikach wykonywalnych, możesz zrobić coś takiego:

    find . -type f -executable -printf "%i.%D %s %m %U %G %C@ %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
    

    W powyższym przykładzie plik jest pełny pathname jest w ostatnim polu i musi odzwierciedlać miejsce, w którym go szukasz za pomocą awk "NAME=$(awk' {print $NF} '

     2
    Author: louigi600,
    Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
    2016-09-02 09:25:48

    To jest tak Śmieszne że to nie jest super-łatwe... a co dopiero obok niemożliwego . Ręce do góry, zdaję się na Apple / Spotlight...

    mdfind 'kMDItemContentType=public.unix-executable'

    Przynajmniej działa!
     1
    Author: Alex Gray,
    Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
    2015-03-13 19:00:51

    Cóż, łatwa odpowiedź brzmiałaby: "Twoje pliki wykonywalne znajdują się w katalogach zawartych w zmiennej PATH", ale tak naprawdę nie znajdowałoby to twoich plików wykonywalnych i i tak mogłoby ich zabraknąć.

    Nie wiem zbyt wiele o Macu, ale myślę, że "mdfind' kMDItemContentType=public.unix-executable '" może brakować takich rzeczy jak interpretowane Skrypty

    Jeśli można znaleźć pliki z ustawionymi bitami wykonywalnymi (niezależnie od tego, czy są one rzeczywiście wykonywalne), to jest w porządku do

    find . -type f -perm +111 -print
    

    Tam, gdzie jest obsługiwana opcja "- executable", zrobi kolejny filtr patrząc na ACL i inne artefakty uprawnień, ale technicznie niewiele różni się od"- pemr +111".

    Być może w przyszłości find będzie obsługiwał "- magic " i pozwoli ci jawnie szukać plików o określonym magicznym id ... ale wtedy musiałbyś określić, aby wyczyścić wszystkie formaty wykonywalne magic id.

    Nie jestem świadomy technicznie poprawnego łatwego wyjścia na unix.

     1
    Author: louigi600,
    Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
    2016-03-21 11:16:52

    Miałem ten sam problem, a odpowiedź była w Kod źródłowy dmenu : Narzędzie stest stworzone w tym celu. Możesz skompilować ' stest.c ' i ' arg.pliki h i powinno działać. Istnieje strona podręcznika do użycia, którą umieściłem tam dla wygody:

    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)
    
     0
    Author: Josuah Demangeon,
    Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
    2016-07-26 17:00:29