Jak mogę znaleźć tylko pliki wykonywalne w określonym katalogu w systemie Linux?

156

Jak mogę znaleźć tylko pliki wykonywalne w określonym katalogu w systemie Linux?

HaiYuan Zhang
źródło
Oto rodzaj skryptu BASH, nie jest źle, co mogę powiedzieć :) stackoverflow.com/a/20209457/2067125
AjayKumarBasuthkar
Co powiesz na użycie standardowego filepolecenia ?
Przełom
4
Dla każdego, kto chce to zrobić na komputerze Mac (testowane w systemie OS X 10.9.5): ls -l | egrep '^[^d]..x..x..x.*$' Powyższe spowoduje wyświetlenie wszystkich plików wykonywalnych (dla wszystkich / użytkowników i grup) w bieżącym katalogu. Uwaga : Ta -executableopcja nie działa na komputerze Mac, dlatego powyższe obejście.
techfoobar
1
@techfoobar: Pytanie jest dwuznaczne: Czy oznacza to pliki zawierające kod wykonywalny, czy oznacza pliki, które mają uprawnienia do wykonywania? Ale nawet jeśli założymy, że potrzebne jest zezwolenie na wykonanie (jak wydaje się większość odpowiedzi), pytanie nie mówi o wykonywalności na świecie . Twoje rozwiązanie znajdzie pliki (a także fifos, gniazda, dowiązania symboliczne itp. -rwxr-x---), Które mają uprawnienia do wykonywania na całym świecie, ale nie mają 750 ( ), które nadal mogą być wykonywane przez niektórych użytkowników.
G-Man,

Odpowiedzi:

157

Sprawdzanie plików wykonywalnych można wykonać za pomocą -perm(niezalecane) lub -executable(zalecane, ponieważ uwzględnia ACL). Aby użyć -executableopcji:

find <dir> -executable

jeśli chcesz znaleźć tylko pliki wykonywalne i nie przeszukiwalne katalogi, połącz z -type f:

find <dir> -executable -type f
knittl
źródło
23
shebang nie oznacza, że ​​są wykonywalne. mówi nam tylko, jakiego tłumacza użyć. i definicji Linux „pliki wykonywalne” są pliki z wykonywalnego (x) ustawionym bitem
Knittla
2
Która wersja find obsługuje ten typ dla -type? man znajdź w moim systemie listy b, c, d, p, f, l, s oraz D.
innaM
2
To samo tutaj, moje znalezisko też nie ma -type x.
davr
7
Jeśli masz starą wersję find (prawdopodobnie wcześniejszą niż 4.3.8), której brakuje -wykonalne użycie find. -perm / u = x, g = x, o = x.
Ludwig Weinzierl
8
find: invalid predicate -executable'na RHEL
SSH
33

Użyj opcji znalezienia -perm. Znajduje pliki w bieżącym katalogu, które mogą być wykonywane przez ich właściciela, członków grupy lub przez inne osoby:

find . -perm /u=x,g=x,o=x

Edytować:

Właśnie znalazłem inną opcję, która jest obecna przynajmniej w GNU find 4.4.0:

find . -executable

Powinno to działać jeszcze lepiej, ponieważ uwzględniane są również listy ACL.

innaM
źródło
2
Działa to tylko w nowszej wersji find. Ten, który jest domyślnie dostarczany z CentOS, podaje błąd find: invalid mode / u = x, g = x, o = x''
davr
12
Następnie powinieneś wypróbować wersję „-perm +”, która jest już nieaktualna w GNU find: find. -perm +111 "
innaM
Wygląda na to, że -perm /111może być najbardziej przenośną wersją.
Scott
12

Wiem, że pytanie konkretnie wspomina o Linuksie, ale ponieważ jest to pierwszy wynik w Google, chciałem tylko dodać odpowiedź, której szukałem (na przykład, jeśli jesteś - tak jak ja w tej chwili - zmuszony przez twojego pracodawcę do korzystania z systemu innego niż GNU / Linux).

Testowane na macOS 10.12.5

find . -perm +111 -type f
friederbluemle
źródło
1
Działa również w RHEL 5.
José Tomás Tocino
To jedyny wariant, w którym mogłem pracować na systemie OS X 10.14, dzięki
Justin
3

Mam inne podejście, na wypadek, gdyby naprawdę chciało się po prostu zrobić coś z plikami wykonywalnymi - i niekoniecznie zmuszać się do znalezienia filtru:

for i in `find -type f`; do [ -x $i ] && echo "$i is executable"; done

Wolę to, ponieważ nie zależy od tego, -executablektóra platforma jest specyficzna; i nie zależy od tego, -permco jest nieco tajemnicze, trochę specyficzne dla platformy, i jak napisano powyżej, wymaga, aby plik był wykonywalny dla wszystkich (nie tylko dla ciebie).

Jest -type fto ważne, ponieważ w katalogach * nix musi być wykonywalny, aby można je było przechodzić, a im więcej zapytań znajduje się w findpoleceniu, tym bardziej wydajna będzie pamięć.

W każdym razie oferuje inne podejście, ponieważ * nix to kraina miliardów podejść.

Mark McKenna
źródło
(0) Które wolisz, tajemnicze i poprawne czy intuicyjne i wadliwe? Wolę poprawnie. (1)  Odpowiedź innejM , gościnnie find -perm, wyszukuje pliki, które mają ustawiony dowolny bit wykonywania. (2) Natomiast ta odpowiedź znajduje tylko pliki, dla których bieżący użytkownik ma uprawnienia do wykonywania. To prawda, że ​​może tego chce OP, ale nie jest jasne. … (Ciągdalszy)
Scott
(Ciąg dalszy)… (3) Dla jasności możesz chcieć zmienić `…`na $(…)- zobacz to , to i to . (4) Ale nie rób for i in $(find …); do …; nie powiedzie się w nazwach plików zawierających spacje. Zamiast tego zrób find … -exec …. (5) A kiedy pracujesz ze zmiennymi powłoki, zawsze cytuj je (w podwójnych cudzysłowach), chyba że masz dobry powód, aby tego nie robić i jesteś pewien, że wiesz, co robisz.
Scott
@ scott OK, poprawiam się :) Przeczytałem -permargument jako wymagający wszystkich trzech, a nie jednego. Ponadto dziękuję za wkład w ochronę argumentów powłoki, to wszystko, o czym nie wiedziałem.
Mark McKenna,
@MarkMcKenna masz tam literówkę: for i in znajdź. -typ f ; do [ -x $i ] && echo "$i is executable"; done; brakuje ci części <katalog>, której używam kropki (.)
Devy
2

Plik oznaczony jako wykonywalny nie musi być plikiem wykonywalnym ani plikiem lub obiektem, który można załadować.

Oto czego używam:

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
AjayKumarBasuthkar
źródło
2
Co to robi?
DerMike,
@DerMike, Jest to jeden ze sposobów znalezienia pliku wykonywalnego w bieżącym katalogu, w tym plików .so, nawet jeśli plik nie jest oznaczony jako plik wykonywalny, który może wykryć.
AjayKumarBasuthkar
To znaczy, jak to robi?
DerMike,
Czyta z nagłówka pliku, aby odkryć, każdy plik binarny lub plik skryptu ma nagłówek.
AjayKumarBasuthkar
O ile mi wiadomo, -name "*"nie ma wpływu na find- zwykle znajduje wszystkie pliki, które nie są eliminowane przez testy.
G-Man,
1

Jako fan jednego linera ...

find /usr/bin -executable -type f -print0 | xargs file | grep ASCII

Użycie „xargs” do pobrania danych wyjściowych z polecenia find (użycie print0 w celu zapewnienia poprawnej obsługi nazw plików ze spacjami). Mamy teraz listę plików, które można wykonać i podajemy je jeden po drugim jako parametr polecenia „file”. Następnie grep dla terminu ASCII, aby zignorować pliki binarne. Zastąp -executable w poleceniu find preferowanym stylem (patrz wcześniejsze odpowiedzi) lub działaniem w twoim systemie operacyjnym NIX

Wymagałem powyższego, aby znaleźć pliki eval w skryptach należących do roota, więc stworzyłem następujące informacje, aby pomóc w wykryciu słabości eskalacji prywatnych, w których użytkownik root uruchamia skrypty o niebezpiecznych parametrach ...

echo -n "+ Identifying script files owned by root that execute and have an eval in them..."
find /  -not \( -path /proc -prune \)  -type f -executable -user root -exec grep -l eval {} \; -exec file {} \; | grep ASCII| cut -d ':' -f1 > $outputDir"/root_owned_scripts_with_eval.out" 2>/dev/null &
Richard Braganza
źródło
To nie zadziała, jeśli skrypt zawiera znaki spoza ASCII. filezgłasza kodowanie, więc skrypt w języku Python można zgłosić jako a /usr/bin/python script, UTF-8 Unicode text executable. find ... | xargs file -b | grep -v '^ELF'może działać lepiej, aby wykryć pliki niebinarne.
ksenoid
0

~/.bashrcDziś wieczorem utworzyłem funkcję, aby znaleźć pliki wykonywalne nie w ścieżce systemowej, a nie w katalogach:

# Quickly locate executables not in the path
xlocate () {
    locate -0r "$1" | xargs -0 -I{} bash -c '[[ -x "$1" ]] && [[ ! -d "$1" ]] \
        &&  echo "executable: $1"'  _  {}
} # xlocate ()

Zaletą jest to, że przeszuka trzy dystrybucje systemu Linux i instalację systemu Windows w ciągu sekundy, gdzie findpolecenie zajmuje 15 minut.

Na przykład:

$ time xlocate llocate
executable: /bin/ntfsfallocate
executable: /home/rick/restore/mnt/e/bin/llocate
executable: /mnt/clone/bin/ntfsfallocate
executable: /mnt/clone/home/rick/restore/mnt/e/bin/llocate
executable: /mnt/clone/usr/bin/fallocate
executable: /mnt/e/bin/llocate
executable: /mnt/old/bin/ntfsfallocate
executable: /mnt/old/usr/bin/fallocate
executable: /usr/bin/fallocate

real    0m0.504s
user    0m0.487s
sys     0m0.018s

Lub dla całego katalogu i wszystkich jego subskrybentów:

$ time xlocate /mnt/e/usr/local/bin/ | wc -l
65

real    0m0.741s
user    0m0.705s
sys     0m0.032s
WinEunuuchs2Unix
źródło