Eine Datei ohne Endung, ein unbekanntes Programm oder ein Befehl, der sich anders verhält als erwartet: Unter Linux gibt es verschiedene Möglichkeiten herauszufinden, womit du gerade arbeitest.
Dabei beantworten file und type unterschiedliche Fragen: file untersucht Dateien und erkennt anhand ihrer Eigenschaften und Inhalte einen wahrscheinlichen Dateityp. type zeigt dagegen, wie deine Shell einen Befehlsnamen interpretiert – beispielsweise als Alias, eingebauten Befehl oder ausführbare Datei.
Dateinamen und Endungen sind nur Hinweise
Eine Endung wie .txt, .jpg oder .tar.gz hilft bei der Orientierung. Sie ist aber kein zuverlässiger Beweis für den tatsächlichen Inhalt.
Eine Bilddatei bleibt beispielsweise eine Bilddatei, wenn sie lediglich in notizen.txt umbenannt wird. Für eine fundiertere Identifizierung untersucht file deshalb unter anderem Dateieigenschaften, charakteristische Bytefolgen und Textmerkmale.
Dateien mit file identifizieren
Die grundlegende Schreibweise lautet:
file DATEI
Beispiel:
file notizen.txt
Eine mögliche Ausgabe:
notizen.txt: ASCII text
Bei anderen Dateien können beispielsweise folgende Angaben erscheinen:
| Ausgabe oder Bestandteil | Bedeutung |
|---|---|
ASCII text | Text aus dem ASCII-Zeichensatz |
Unicode text, UTF-8 text | Als UTF-8 erkannter Text |
PNG image data | PNG-Bilddaten |
PDF document | Ein PDF-Dokument |
gzip compressed data | Mit gzip komprimierte Daten |
ELF 64-bit … | Eine Datei im ELF-Format, beispielsweise ein kompiliertes Programm |
directory | Ein Verzeichnis |
symbolic link to … | Ein symbolischer Link |
empty | Eine leere Datei |
data | Daten, die nicht genauer eingeordnet werden konnten |
Die genaue Ausgabe hängt vom Inhalt und von der verwendeten Version beziehungsweise Erkennungsdatenbank ab. data bedeutet nicht automatisch, dass eine Datei beschädigt ist.
Mehrere Dateien untersuchen
file notizen.txt bild.png archiv.tar.gz
Mein Favorite für sichtbare Einträge im aktuellen Verzeichnis:
file -- ./*
Das -- beendet die Optionsauswertung. Das Muster ./* wird von der Shell erweitert und erfasst standardmäßig keine versteckten Namen. Unterverzeichnisse werden dabei als Einträge erkannt, aber nicht rekursiv durchsucht.
Nur die Beschreibung ausgeben
Mit -b entfällt der Dateiname vor dem Ergebnis:
file -b notizen.txt
Mögliche Ausgabe:
ASCII text
Das ist hilfreich, wenn du nur die Typbeschreibung benötigst.
Wie erkennt file einen Dateityp?
file arbeitet im Wesentlichen mit drei Gruppen von Tests:
- Dateisystemtests: Handelt es sich beispielsweise um ein Verzeichnis, eine leere Datei oder einen Link?
- Signaturtests: Enthalten die Daten charakteristische Muster eines bekannten Formats?
- Texttests: Sehen die Daten nach Text aus, und gibt es Hinweise auf Zeichencodierung oder eine bestimmte Sprache?
Charakteristische Signaturen werden oft als „Magic Numbers“ bezeichnet. Sie müssen nicht ausschließlich aus Zahlen bestehen und auch nicht immer direkt am Dateianfang liegen.
Die Erkennung ist dennoch eine Einordnung, keine vollständige Validierung. Eine als PDF erkannte Datei muss deshalb weder vollständig intakt noch ungefährlich sein.
MIME-Typ und Zeichencodierung anzeigen
Ein MIME-Typ ist eine standardisierte Bezeichnung für die Art und das Format von Daten. Er besteht aus einem Haupttyp und einem Untertyp, getrennt durch
/, beispielsweisetext/plainfür einfachen Text,image/pngfür PNG-Bilder oderapplication/pdffür PDF-Dokumente. Programme nutzen diese Angabe, um Daten passend zu verarbeiten.
Mit -i erhältst du eine standardisierte Beschreibung:
file -i notizen.txt
Mögliche Ausgabe:
notizen.txt: text/plain; charset=us-ascii
Die Bestandteile:
text/plain: MIME-Typ für einfachen Text.charset=us-ascii: Erkannte Zeichencodierung.
Du kannst die Angaben auch getrennt abfragen:
file --mime-type notizen.txt
file --mime-encoding notizen.txt
Das ist nützlich, wenn du Textverarbeitungsprobleme untersuchst oder Dateitypen in einem Skript unterscheiden möchtest. Auch die Zeichencodierung wird aus den Daten abgeleitet und ist nicht in jedem Fall eindeutig bestimmbar.
Symbolische Links mit file untersuchen
Bei einem symbolischen Link musst du unterscheiden, ob du den Link selbst oder dessen Ziel untersuchen möchtest.
Den Link selbst identifizieren
file -h notizen-link
Mögliche Ausgabe:
notizen-link: symbolic link to notizen.txt
-h legt ausdrücklich fest, dass dem Link nicht gefolgt wird. Das ist beim verbreiteten file normalerweise auch das Standardverhalten; die Umgebungsvariable POSIXLY_CORRECT kann diesen Standard jedoch verändern.
Den Inhalt des Linkziels identifizieren
file -L notizen-link
Mit -L folgt file dem Link und untersucht dessen Ziel:
notizen-link: ASCII text
So kannst du gezielt zwischen „Was ist dieser Eintrag?“ und „Was befindet sich hinter diesem Verweis?“ unterscheiden.
Dateieigenschaften mit stat untersuchen
Während file den Inhalt beziehungsweise Typ einordnet, zeigt stat Metadaten:
stat notizen.txt
Die Ausgabe enthält unter anderem:
- Dateityp.
- Logische Größe und belegte Blöcke.
- Inode-Nummer.
- Anzahl der harten Links.
- Zugriffsrechte.
- Eigentümer und Gruppe.
- Verschiedene Zeitstempel.
Damit beantwortest du nicht „Ist das ein PDF?“, sondern beispielsweise „Wem gehört diese Datei?“ oder „Welche Rechte und Zeitstempel besitzt sie?“.
Kompakte Ausgabe unter GNU/Linux
Mit stat kannst du die Ausgabe selbst gestalten:
stat -c 'Name: %n | Typ: %F | Größe: %s Bytes' notizen.txt
Dabei steht:
| Platzhalter | Bedeutung |
|---|---|
%n | Dateiname |
%F | Dateityp im Dateisystem |
%s | Logische Größe in Bytes |
Der Typ aus %F ist beispielsweise „reguläre Datei“ oder „Verzeichnis“, nicht das inhaltliche Format wie PNG oder PDF. Die konkreten Bezeichnungen können von der Spracheinstellung abhängen.
Links und ihre Ziele unterscheiden
stat notizen-link
beschreibt standardmäßig den Link selbst.
stat -L notizen-link
beschreibt dessen Ziel.
Befehle mit type identifizieren
type ist kein Werkzeug zur Erkennung von Dateiformaten. Es beantwortet eine andere Frage:
Was würde die Shell unter diesem Befehlsnamen ausführen?
Die folgenden Beispiele beziehen sich auf Bash:
type cd
Eine typische Ausgabe:
cd is a shell builtin
cd ist hier ein eingebauter Shell-Befehl und keine separate Programmdatei.
Bei einem externen Programm könnte die Ausgabe so aussehen:
type tar
tar is /usr/bin/tar
Der konkrete Pfad hängt vom System ab.
Welche Arten von Befehlen gibt es?
Mit -t liefert Bash eine kurze Kategorie:
type -t cd
Ausgabe:
builtin
Mögliche Kategorien sind:
| Ausgabe | Bedeutung |
|---|---|
alias | Eine definierte Kurzform für einen Befehl |
keyword | Ein reserviertes Shell-Wort, beispielsweise if |
function | Eine Shell-Funktion |
builtin | Ein eingebauter Shell-Befehl |
file | Eine ausführbare Datei |
Das Wort file bezeichnet hier eine Kategorie. Es ist keine Ausgabe des gleichnamigen Programms zur Dateierkennung.
Alle verfügbaren Varianten anzeigen
type -a ls
Falls auf deinem System ein Alias eingerichtet ist, könnte die Ausgabe beispielsweise lauten:
ls is aliased to `ls --color=auto'
ls is /usr/bin/ls
ls is /bin/ls
Die tatsächlichen Ergebnisse hängen von deiner Shell-Konfiguration und deinem Suchpfad ab. Mehrere angezeigte Pfade müssen außerdem nicht auf unterschiedliche Programminhalte verweisen.
type -a ist besonders hilfreich, wenn ein Alias oder eine Funktion einen gleichnamigen externen Befehl überlagert.
Der schnelle Überblick mit ls -l
Für eine erste Einordnung reicht häufig ls:
ls -ld -- datei
Ein Ausgabe könnte so aussehen:
drwxr-xr-x. 1 andy andy 6702 7. Nov 16:31 Downloads
lrwxrwxrwx. 1 andy andy 9 7. Nov 16:19 hallo-link -> hallo.txt
-rw-r--r--. 1 andy andy 12 6. Nov 21:29 hallo.txt
Das erste Zeichen in der jeweiligen Zeil der langen Ausgabe beschreibt die Art des Dateisystemeintrags:
| Zeichen | Bedeutung |
|---|---|
- | Reguläre Datei |
d | Verzeichnis |
l | Symbolischer Link |
b | Blockgerät |
c | Zeichengerät |
p | Benannte Pipe |
s | Socket |
ls erkennt damit die Art des Eintrags, nicht dessen inhaltliches Format. Eine Textdatei, ein Bild und ein kompiliertes Programm können hier alle als reguläre Datei erscheinen.
Mit Inode-Nummern:
ls -li datei1 datei2
Das hilft beim Vergleich harter Links: Gleiche Inode-Nummern weisen nur innerhalb desselben Dateisystems auf dieselbe Datei hin.
Ein Inode ist eine Datenstruktur im Dateisystem, die Informationen zu einer Datei speichert, etwa Eigentümer, Rechte, Größe und Zeitstempel sowie Verweise auf ihre Daten. Der Dateiname steht nicht im Inode, sondern im zugehörigen Verzeichniseintrag.
Für eine genauere Gegenüberstellung kannst du zusätzlich die Gerätekennung mit stat anzeigen:
stat -c 'Gerät: %d | Inode: %i | Name: %n' datei1 datei2
Erst die Kombination aus Dateisystem beziehungsweise Gerät und Inode ist hier aussagekräftig.
Ein einfacher Ablauf für unbekannte Dateien
Angenommen, du erhältst eine Datei namens download, deren Inhalt du nicht kennst.
Schritt 1: Den Eintrag ansehen
ls -l download
Ist es eine reguläre Datei, ein Verzeichnis oder ein symbolischer Link?
Schritt 2: Den Typ bestimmen
file -h download
Bei einem Link kannst du dessen Ziel anschließend ausdrücklich untersuchen:
file -L download
Schritt 3: Bei Bedarf Metadaten ergänzen
stat download
Du kombinierst damit drei Perspektiven: Dateisystemeintrag, erkannter Inhalt und Metadaten. Keiner dieser Befehle verlangt, das unbekannte Programm selbst auszuführen. Eine Typbeschreibung allein ist allerdings kein Sicherheitsnachweis.
Wenn du stattdessen einen Befehlsnamen untersuchst, beginnst du mit:
type -a befehlsname
Damit klärst du zuerst, welche Bedeutung dieser Name in deiner aktuellen Shell hat.
Fazit: Dateityp und Befehlstyp auseinanderhalten
Für die Identifizierung unter Linux sind vor allem vier Fragen wichtig:
| Frage | Werkzeug |
|---|---|
| Was für einen Inhalt hat diese Datei vermutlich? | file |
| Was bedeutet dieser Befehlsname in meiner Shell? | type, command -v |
| Welche Metadaten besitzt der Eintrag? | stat |
| Welche Art von Dateisystemeintrag liegt vor? | ls -l |
file und type ergänzen sich also, untersuchen aber nicht dasselbe. Wer diesen Unterschied kennt, kann unbekannte Dateien einordnen und zugleich nachvollziehen, welches Programm oder welche Shell-Funktion hinter einem eingegebenen Befehl steckt.
