¿Cómo se conocen los tipos de archivo si no es por el sufijo de archivo?

55

Me gustaría saber cómo se conocen los tipos de archivo si los nombres de archivo no tienen sufijos.

Por ejemplo, un archivo llamado myfilepodría ser binario o de texto, ¿cómo sabe el sistema si el archivo es binario o de texto?

Niklas Rosencrantz
fuente
3
Solo un comentario, el resto de las respuestas cubren todo. Hoy en día puede suceder que con una configuración regional mal configurada o ejecutables antiguos, algunos archivos utf-8 puedan ser mal detectados como datos binarios debido a bytes no ascii.
orion
19
Al sistema no le importa. Ciertas aplicaciones pueden importar, pero cada una tiene sus propias formas de manejar esto.
jwodder
2
Tenga en cuenta que incluso para archivos normales (no archivos de dispositivo, zócalos de dominio Unix, canalizaciones con nombre, etc.) "tipo de archivo" puede significar dos cosas diferentes: (1) Un formato de archivo particular (".docx", XML, formato de texto MS-DOS , RTF, registros de longitud fija, la lista podría ser muy larga) o (2) Un archivo con el que una aplicación en particular sabe cómo tratar (".xlsx" o ".doc" o lo que sea, se superpone con el tipo de formato) . Vale la pena tener en cuenta esa distinción cuando se habla de "tipo de archivo".
Bruce Ediger
@jwodder El sistema cuida. Es el sistema el que se queja de que no puede ejecutar un archivo no ejecutable cuando lo intenta, ¡no esas aplicaciones!
Sr. Lister
1
@MrLister Verdadero, pero ejecutable / no ejecutable no tiene nada que ver con 'extensión'.
user2338816

Respuestas:

84

La fileutilidad determina el tipo de archivo de 3 formas:

Primero las pruebas del sistema de archivos : dentro de esas pruebas , se invoca una de las llamadas al sistema de la familia de estadísticas en el archivo. Esto devuelve los diferentes tipos de archivos Unix : archivo normal, directorio, enlace, dispositivo de caracteres, dispositivo de bloque, canalización con nombre o un socket. Dependiendo de eso, se hacen las pruebas mágicas.

Las pruebas mágicas son un poco más complejas. Los tipos de archivos son adivinados por una base de datos de patrones llamada el archivo mágico . Algunos tipos de archivos se pueden determinar leyendo un bit o número en un lugar particular dentro del archivo (binarios, por ejemplo). El archivo mágico contiene " números mágicos " para probar el archivo si los contiene o no y qué información de texto debe imprimirse. Esos " números mágicos " pueden ser valores de 1-4 Bytes, cadenas, fechas o incluso expresiones regulares. Con más pruebas se puede encontrar información adicional. En el caso de un ejecutable, la información adicional sería si está vinculado dinámicamente o no, despojadoo no o la arquitectura. A veces, deben pasar varias pruebas antes de que el tipo de archivo pueda identificarse realmente. Pero de todos modos, no importa cuántas pruebas se realicen, siempre es una buena suposición .

Aquí están los primeros 8 bytes en un archivo de algunos tipos de archivos comunes que pueden ayudarnos a tener una idea de cómo pueden ser estos números mágicos:

             Hexadecimal          ASCII
PNG   89 50 4E 47|0D 0A 1A 0A   ‰PNG|....
JPG   FF D8 FF E1|1D 16 45 78   ÿØÿá|..Ex
JPG   FF D8 FF E0|00 10 4A 46   ÿØÿà|..JF
ZIP   50 4B 03 04|0A 00 00 00   PK..|....
PDF   25 50 44 46|2D 31 2E 35   %PDF|-1.5

Si el tipo de archivo no se puede encontrar en las pruebas mágicas, el archivo parece ser un archivo de texto y filebusca la codificación de los contenidos. La codificación se distingue por los diferentes rangos y secuencias de bytes que constituyen texto imprimible en cada conjunto.

Los saltos de línea también se investigan, según sus valores HEX:

  • 0A( \n) clasifica un archivo terminado Un * x / Linux / BSD / OSX
  • 0D 0A( \r\n) son archivos de los sistemas operativos de Microsoft
  • 0D( \r) sería Mac OS hasta la versión 9
  • 15( \025) sería AIX de IBM

Ahora comienzan las pruebas de idioma . Si parece ser un archivo de texto, se busca en el archivo cadenas particulares para averiguar qué idioma contiene (C, Perl, Bash). Algunos lenguajes de script también se pueden identificar sobre el hashbang ( #!/bin/interpreter) en la primera línea del script.

Si no se aplica nada al archivo, el tipo de archivo no se puede determinar y filesolo imprime "datos".

Entonces, ves que no hay necesidad de un sufijo. Un sufijo de todos modos podría confundir, si se configura mal.

caos
fuente
44
También está la base de datos MIME compartida freedesktop.org, que es utilizada esencialmente por todas las aplicaciones X11. Esto es similar en concepto a lo que file(1)hace, pero con una implementación (muy) diferente.
lcd047
44
Tenga en cuenta que el resultado de este proceso es básicamente una suposición, y no se debe confiar en nada importante. (Las funciones de conveniencia, como decidir el programa predeterminado para abrir el archivo, están bien)
user253751
Entonces, si agrego% PNG en la parte superior de un archivo de texto, se verá como un archivo png. ¿¿Derecho??
saga
@saga Si obtiene la codificación correcta y si coloca un signo por mil en lugar de un signo de porcentaje, entonces: tal vez. Puede haber pruebas adicionales.
Bananguin
19

A menudo no le importa. Simplemente lo pasa a un programa y lo interpreta o no lo hace. Puede que no sea útil abrir un .jpg en un editor de texto, pero no se le impide hacerlo. La extensión, como el resto del nombre de archivo, es para la conveniencia organizacional de los humanos.

También es posible construir archivos que se puedan interpretar de manera válida de varias maneras. Debido a que el formato del archivo ZIP comienza tiene un encabezado al final del archivo , puede anteponer otras cosas al frente y aún se cargará como un archivo ZIP. Esto se usa comúnmente para hacer archivos zip autoextraíbles.

pjc50
fuente
44
Re el último párrafo: Funky File Formats es una charla interesante sobre ese tema, presentando, por ejemplo, un jpeg que también es un programa java hello world, después de que AES lo encripta se convierte en PNG, o después de que 3DES lo desencripta se convierte en PDF y más ( todo con contenido "interesante", es decir, no solo con ruido blanco o artefactos)
Hagen von Eitzen
14

Esa información se encuentra comúnmente en el encabezado del archivo. El filecomando analiza el objetivo y le brinda información sobre el archivo. A menudo se deriva mucha información de los encabezados de los archivos, que a menudo son los primeros bytes de un archivo (ver más abajo). El sistema utiliza los encabezados para descubrir cómo manejar los archivos. #!/bin/bashal principio de un archivo le dice al sistema que use el shell bash para interpretar el siguiente script. ELFle dice al sistema que este es un ejecutable ELF.

[~] root@www # file /bin/ls
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped

[~] root@www # file /etc/passwd
/etc/passwd: ASCII text

Ejemplos de encabezado de archivo:

[root@server4 ~]# xxd old_sm_logo.png | head -5
0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR
0000010: 0000 0134 0000 006f 0806 0000 0062 bf3c  ...4...o.....b.<

[root@server4 ~]# xxd /bin/ls | head -5
0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
0000010: 0200 3e00 0100 0000 a024 4000 0000 0000  ..>......$@.....

[root@server4 proj]# xxd resizer.sh | head -5
0000000: 2321 2f62 696e 2f62 6173 680a 5b20 2d7a  #!/bin/bash.[ -z
0000010: 2022 2431 2220 5d20 2626 2065 6368 6f20   "$1" ] && echo
h3rrmiller
fuente
3
Esto es bastante engañoso. Los archivos Unix no tienen un "encabezado" per se. El filecomando intenta adivinar a partir del contenido del archivo cómo es probable que se use el archivo. No es infalible.
Nate Eldredge
Tienes razón en cómo explicaste el comportamiento de file. De hecho, hace un análisis del archivo. Sin embargo, la mayoría de los tipos de archivos se identifican por una especie de encabezado. 0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............es un encabezado de un ejecutable ELF (primeros bytes de / bin / ls). De manera similar, #!/bin/bashen la parte superior de un archivo ASCII lo identificaría como un script de shell. Otro ejemplo: 0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR(una imagen .png)
h3rrmiller
2
Pero su respuesta hace que parezca que un encabezado es una característica inherente de un archivo Unix. Los archivos de texto, por ejemplo, no tienen ese encabezado; alguien como el OP probablemente consideraría que un archivo fuente C y un archivo fuente Java tienen diferentes "tipos de archivos", pero no hay un encabezado para distinguirlos. Yo diría que "tipo de archivo" ni siquiera es un concepto significativo en Unix; el sistema operativo solo proporciona un sistema de archivos, y depende de cada aplicación decidir qué significan los contenidos de cualquier archivo dado.
Nate Eldredge
Estoy de acuerdo. Intentaba responder de la manera más simple posible sin tener que atravesar demasiadas madrigueras.
h3rrmiller
7

Lo primero que debe verificar es el tipo de archivo codificado que el núcleo reconoce. Estos son los tipos de archivo como directorio, archivo especial de caracteres, archivo especial de bloque, archivo especial de canalización, socket y enlace simbólico. Esta información proviene del inodo del archivo. Si el archivo es un archivo simple, el siguiente conjunto de información proviene de los primeros 256 bytes buscando patrones. Por lo tanto, los archivos de texto y el código fuente C se reconocen al examinar esos bytes. Además, las utilidades también buscan un número mágico que se utiliza para probar y validar el tipo de archivo. Puede agregar sus propios tipos de archivos para que sean reconocidos agregando la información al archivo /etc/magic. Consulte la página del manual para magic(5)ver el formato del archivo mágico.

En implementaciones anteriores (Solaris, por ejemplo), el archivo /etc/magicenumeraba la mayoría de los tipos de archivos reconocidos.

unxnut
fuente
4

El filecomando aplica algunas heurísticas al inspeccionar (partes de) el archivo y hacer una suposición calificada. Más allá de eso, hay algunos casos especiales en los que se puede obtener información adicional; como #!al principio de un archivo de texto, una BoM (marca de orden de bytes) o bytes de encabezado específicos de formatos de archivo ejecutables. El #!sistema utiliza las marcas binarias y binarias en los ejecutables para diferenciarlas.

Janis
fuente
4

El sistema no sabe si un archivo es binario o de texto. En todos los sistemas operativos (que yo sepa) de tipo Unix, fopen(path, "rb")es exactamente la misma que fopen(path "r")- el bno tiene ningún efecto. Se acepta porque el estándar C debe ser portátil para algunos otros sistemas operativos que hacen tal distinción.

Toby Speight
fuente
0

Yo diría que "tipo de archivo" ni siquiera es un concepto significativo en Unix;

En los viejos tiempos de los computadores mainframe, sus sistemas operativos admitían varios tipos de archivos, incluidos secuenciales e secuenciales de índice. Los sistemas operativos modernos (Un * x y posiblemente Windows) reducen el conjunto de tipos de archivos al mínimo (incluido el objeto ejecutable y compartido).

También es posible construir archivos que se puedan interpretar de manera válida de varias maneras.

Es posible, hay un formato de archivo complicado: un fragmento de código C que puede interpretarse como una descripción de imagen. Además hay diferentes formatos cada vez menos específicos: archivo de texto, archivo XML, un documento SOAP.

ijbalazs
fuente
1
A medida que avanzan los formatos de archivo, XPM no es tan complicado. Considero "complicado" comenzar con algo que sea un archivo JPEG válido y un archivo ZIP válido.
Mark