Wie finde ich unter Linux nur die ausführbaren Dateien in einem bestimmten Verzeichnis?

157

Wie finde ich unter Linux nur die ausführbaren Dateien in einem bestimmten Verzeichnis?

HaiYuan Zhang
quelle
Hier ist eine Art BASH-Skript, es ist nicht schlecht, was ich sagen kann :) stackoverflow.com/a/20209457/2067125
AjayKumarBasuthkar
Was ist mit dem Standard - fileBefehl ?
Durchbruch
5
Für alle, die dies auf einem Mac tun möchten (getestet unter OS X 10.9.5): ls -l | egrep '^[^d]..x..x..x.*$' Die oben stehende Liste listet alle ausführbaren Dateien (für alle / Benutzer und Gruppen) im aktuellen Verzeichnis auf. Hinweis : Die -executableOption funktioniert nicht auf einem Mac, daher die oben beschriebene Problemumgehung.
Techfoobar
Ebenfalls relevant: Unix find: Suche nach ausführbaren Dateien
Slothworks
1
@techfoobar: Die Frage ist nicht eindeutig: Bedeutet sie Dateien, die ausführbaren Code enthalten, oder Dateien, die über ausführbare Berechtigungen verfügen? Aber selbst wenn wir davon ausgehen, dass eine ausführbare Berechtigung gewünscht wird (wie die Mehrheit der Antworten scheint), sagt die Frage nicht, dass sie von der Welt ausführbar ist . Ihre Lösung findet Dateien (und auch Fifos, Sockets, Symlinks usw.), die über die Berechtigung zum Ausführen auf der ganzen Welt verfügen, jedoch nicht über die Berechtigung 750 ( -rwxr-x---), die für einige Benutzer noch ausführbar ist.
G-Man

Antworten:

157

Das Überprüfen auf ausführbare Dateien kann mit -perm(nicht empfohlen) oder -executable(empfohlen, da ACL berücksichtigt wird) erfolgen. So verwenden Sie die -executableOption:

find <dir> -executable

Wenn Sie nur ausführbare Dateien und keine durchsuchbaren Verzeichnisse finden möchten, kombinieren Sie mit -type f:

find <dir> -executable -type f
stricken
quelle
23
Ein Shebang bedeutet nicht, dass sie ausführbar sind. es sagt uns nur, welcher Interpreter zu verwenden ist. und
laut
2
Welche Version von find unterstützt diesen Typ für -type? Man findet Listen b, c, d, p, f, l, s und D auf meinem System.
Uhr
2
Mein Fund hat auch hier keinen -type x.
Davr
7
Wenn Sie eine alte Version von find haben (wahrscheinlich vor 4.3.8), die nicht ausführbar ist, verwenden Sie find. -perm / u = x, g = x, o = x.
Ludwig Weinzierl
8
find: invalid predicate -executable'auf RHEL
SSH Dies ist der
33

Verwenden Sie die -permSuchoption. Dies findet Dateien im aktuellen Verzeichnis, die entweder von ihrem Besitzer, von Gruppenmitgliedern oder von anderen ausgeführt werden können:

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

Bearbeiten:

Ich habe gerade eine andere Option gefunden, die zumindest in GNU find 4.4.0 vorhanden ist:

find . -executable

Dies sollte noch besser funktionieren, da auch ACLs berücksichtigt werden.

innaM
quelle
2
Dies funktioniert nur bei einer neueren Version von find. find: invalid mode Diejenige, die standardmäßig mit CentOS geliefert wird, gibt den Fehler / u = x, g = x, o = x'`
davr
12
Dann sollten Sie die "-perm +" - Version ausprobieren, die jetzt in GNU find: find veraltet ist. -perm +111 "
innaM
Es scheint, als wäre -perm /111dies die portabelste Version.
Scott
12

Ich weiß, dass in der Frage Linux speziell erwähnt wird, aber da es das erste Ergebnis bei Google ist, wollte ich nur die Antwort hinzufügen, nach der ich gesucht habe (zum Beispiel, wenn Sie - wie ich im Moment - von Ihrem Arbeitgeber gezwungen werden, ein Nicht-GNU-System zu verwenden / Linux-System).

Getestet unter macOS 10.12.5

find . -perm +111 -type f
friederblümle
quelle
1
Funktioniert auch in RHEL 5.
José Tomás Tocino
Dies ist die einzige Variante, die ich unter OS X 10.14 zum Laufen bringen könnte
Justin,
3

Ich habe einen anderen Ansatz, für den Fall, dass Sie wirklich nur etwas mit ausführbaren Dateien tun möchten - und nicht unbedingt herausfinden müssen, um sich selbst zu filtern:

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

Ich bevorzuge dies, weil es nicht darauf ankommt, -executablewelche Plattform spezifisch ist. und es hängt nicht davon ab, -permwelches ein bisschen geheimnisvoll, ein bisschen plattformspezifisch ist, und wie oben beschrieben, muss die Datei für alle (nicht nur für Sie) ausführbar sein.

Dies -type fist wichtig, da in * nix Verzeichnisse ausführbar sein müssen, damit sie durchlaufen werden können. Je mehr sich die Abfrage im findBefehl befindet, desto speichereffizienter ist Ihr Befehl.

Jedenfalls nur einen anderen Ansatz anzubieten, da * nix das Land der Milliarden Ansätze ist.

Mark McKenna
quelle
(0) Welche bevorzugen Sie, arkan und korrekt oder intuitiv und fehlerhaft? Ich ziehe richtig. (1)  Die Antwort von innaM mit find -permfindet Dateien, für die ein Ausführungsberechtigungsbit gesetzt ist. (2) Im Gegensatz dazu findet diese Antwort nur Dateien, für die der aktuelle Benutzer Ausführungsberechtigungen hat. Zugegeben, das ist vielleicht das, was die OP will, aber es ist unklar. … (Fortsetzung)
Scott
(Fortsetzung)… (3) Aus Gründen der Klarheit möchten Sie vielleicht ändern, `…`um $(…)- dies , dies und das zu sehen . (4) Aber tu es nicht for i in $(find …); do …; Es schlägt bei Dateinamen fehl, die Leerzeichen enthalten. Stattdessen tun find … -exec …. (5) Und wenn Sie mit Shell-Variablen arbeiten, zitieren Sie sie immer (in doppelten Anführungszeichen), es sei denn, Sie haben einen guten Grund, dies nicht zu tun, und Sie sind sicher, dass Sie wissen, was Sie tun.
Scott
@scott OK, ich stehe korrigiert :) Ich habe das -permArgument so gelesen, dass es alle drei erfordert, nicht einen von ihnen. Vielen Dank für den Input zum Schutz von Shell-Argumenten, all das war mir nicht bewusst.
Mark McKenna
@MarkMcKenna du hast einen Tippfehler drin: for i in find. -Typ f ; do [ -x $i ] && echo "$i is executable"; done; Ihnen fehlt der Teil <dir>, für den ich einen Punkt (.) verwende
Devy
2

Eine als ausführbar markierte Datei muss keine ausführbare Datei oder ladbare Datei oder ein Objekt sein.

Folgendes verwende ich:

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
quelle
2
Was macht das?
DerMike
@DerMike, Dies ist eine der Möglichkeiten, ausführbare Dateien im aktuellen Verzeichnis zu finden, einschließlich .so-Dateien, selbst wenn eine Datei nicht als ausführbar markiert ist, kann sie gefunden werden.
AjayKumarBasuthkar
Nun, ich meine, wie macht es das?
DerMike
Es liest aus dem Header der Datei, um festzustellen, dass jede Binärdatei oder Skriptdatei einen Header hat.
AjayKumarBasuthkar
Soweit ich weiß, -name "*"hat das keine Auswirkung find- es werden normalerweise alle Dateien gefunden, die nicht durch Tests beseitigt werden.
G-Man
1

Als Fan des One Liner ...

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

Verwenden Sie 'xargs', um die Ausgabe des Befehls find zu übernehmen (verwenden Sie print0, um sicherzustellen, dass Dateinamen mit Leerzeichen korrekt behandelt werden). Wir haben jetzt eine Liste der ausführbaren Dateien und stellen sie einzeln als Parameter für den Befehl 'file' zur Verfügung. Suchen Sie dann nach dem Begriff ASCII, um die Binärdateien zu ignorieren. Ersetzen Sie den Befehl -executable in find durch den von Ihnen bevorzugten Stil (siehe frühere Antworten) oder den auf Ihrem NIX-Betriebssystem verwendeten

Ich benötigte das Obige, um Dateien mit eval in Skripten zu finden, die root gehören. Daher haben wir das Folgende erstellt, um Schwachstellen bei der privaten Eskalation zu finden, bei denen Root-Benutzer Skripten mit unsicheren Parametern ausführen ...

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
quelle
Das funktioniert nicht, wenn das Skript Nicht-ASCII-Zeichen enthält. filemeldet die Codierung, sodass ein Python-Skript als gemeldet werden kann a /usr/bin/python script, UTF-8 Unicode text executable. find ... | xargs file -b | grep -v '^ELF'könnte besser funktionieren, um die Nicht-Binärdateien zu erkennen.
Xenoid
0

Ich habe ~/.bashrcheute Abend eine Funktion erstellt , um ausführbare Dateien zu finden, die nicht im Systempfad und nicht in Verzeichnissen enthalten sind:

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

Der Vorteil ist, dass in weniger als einer Sekunde drei Linux-Distributionen und eine Windows-Installation durchsucht werden, wobei der findBefehl 15 Minuten dauert.

Zum Beispiel:

$ 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

Oder für ein ganzes Verzeichnis und alle Subs:

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

real    0m0.741s
user    0m0.705s
sys     0m0.032s
WinEunuuchs2Unix
quelle