Wie finde ich alle ausführbaren Binärdateien rekursiv in einem Verzeichnis?

46

Wenn ich einen findBefehl wie diesen verwende:

find /mydir/mysubdir -executable -type f

Alle ausführbaren Dateien werden aufgelistet (ausgenommen Verzeichnisse), einschließlich der ausführbaren Skriptdatei (wie script.sh usw.). Ich möchte nur ausführbare Binärdateien auflisten.

uray
quelle
1
Bitte ändern Sie den Betreff, um das Wort "Binär" einzufügen. Dies ist der Schlüssel zur Beantwortung Ihrer Frage.
Stefan Lasiewski

Antworten:

44

Sie könnten das fileDienstprogramm versuchen . Laut der Manpage:

Die Zaubertests werden verwendet, um nach Dateien mit Daten in bestimmten festen Formaten zu suchen. Das kanonische Beispiel hierfür ist eine binäre ausführbare Datei (kompiliertes Programm) a.out, deren Format im und möglicherweise im Standard-Include-Verzeichnis definiert ist.

Möglicherweise müssen Sie mit dem regulären Ausdruck herumspielen, aber so etwas wie:

$ find -type f -executable -exec file -i '{}' \; | grep 'x-executable; charset=binary'

Da die Datei viele Optionen enthält, sollten Sie sich die Manpage genauer ansehen. Ich habe die erste Option verwendet, die ich gefunden habe und die scheinbar einfach zu grep ist.

Steven D
quelle
15
Ich würde sagen verwenden find -type f -executable -exec sh -c "file -i '{}' | grep -q 'x-executable; charset=binary'" \; -print. Es gibt Ihnen nur Dateien (und kann daher an den nächsten Befehl übergeben werden, den er ausführen möchte)
Gert
Die Lösung serverfault.com/a/584595/211551 findet Dateien, die NICHT als ausführbar markiert sind, aber ausführbar.
user2067125
Unter OS X können Sie GNU findmit brew install findutilsoder installieren sudo port install findutilsund dann einen Aufruf wie diesen ausführen, der einen ähnlichen Effekt hat:gfind . -type f -executable -exec file '{}' \; | grep -i execut
GDP2
7

Hier ist eine Möglichkeit zum Ausschließen von Skripten, dh Dateien, deren erste beiden Zeichen sind #!:

find -type f -executable -exec sh -c 'test "$(head -c 2 "$1")" != "#!"' sh {} \; -print

Bei einigen Arten von Dateien ist nicht klar, ob sie als Skripte oder als Binärdateien klassifiziert werden sollen, z. B. Bytecode-Dateien. Je nachdem, wie die Dinge eingerichtet sind, können diese mit beginnen oder auch nicht #!. Wenn dies für Sie von Bedeutung ist, müssen Sie das innere Shell-Skript komplexer gestalten. Im Folgenden sehen Sie beispielsweise, wie Sie ELF-Binärdateien und ausführbare Mono-Dateien und Objective Caml-Bytecode-Programme, jedoch keine anderen Arten von ausführbaren Dateien wie Shell- oder Perl-Skripts oder JVM-Bytecode-Programme einschließen können:

find -type f -executable -exec sh -c '
    case "$(head -n 1 "$1")" in
       ?ELF*) exit 0;;
       MZ*) exit 0;;
       #!*/ocamlrun*) exit 0;;
    esac
    exit 1
' sh {} \; -print
Gilles 'SO - hör auf böse zu sein'
quelle
2

Nur für den Fall, dass Sie sich auf einem System mit einem Downlevel befinden find(es gibt immer noch, wie ich schreibe, eine Menge Wissenschaftscluster, auf denen RHEL5 ausgeführt wird!), Ohne die Rechte zum Aktualisieren: statt

find /mypath/ -executable -type f

In den obigen ausgezeichneten Antworten können Sie z.

find /mypath/h -type f -perm -u+x

die auf Berechtigungsbits sucht. Leider findet das obige nur Dateien, für die der Benutzer eine ausführbare Datei hat, aber das funktioniert normalerweise bei mir.

TomRoche
quelle
Dies würde immer noch ausführbare Skripte finden, nicht nur Binärdateien.
Kusalananda