Filesystem, Usuarios, Grupos y Permisos

Filesystem

En Linux toda la información del sistema está organizada en un único filesystem. Linux hereda el concepto original en Unix de que “todo es un archivo”. Si bien este paradigma no es 100% efectivo en todos los casos, resulta un modelo de organización muy simple, fundamentalmente en la gestión de IO y particularmente en la definición de los permisos de usuarios y grupos.

El filesystem de Linux es un único árbol invertido de directorios, subdirectorios y archivos, que arrancan en la raíz /. Debajo de la raíz se encuentra el primer nivel de directorios y debajo de estos se encuentran los demás niveles de directorios.

La manera de hacer referencia a un archivo o un directorio del filesystem es empleando / para separar nombres de directorios, subdirectorios y archivos.

Por ejemplo: /dir1/dir2/archivo.pdf o /dir3/dir4

Ejemplo de algunos pocos directorios de primer y segundo nivel en Linux

/
├── bin                  <-- Aplicaciones básicas del sistema
├── boot                 <-- Archivos de booteo
│   ├── efi
│   └── grub
├── dev                  <-- Dispositivos
├── etc                  <-- Configuración del sistema y sus servicios
├── home                 <-- homedir de los usuarios
├── lib                  <-- Bibliotecas del sistema
├── lib64
├── media                <-- donde se montan los dispositivos externos (ej. USB)
├── proc                 <-- directorio de los procesos que están corriendo (all is a file!!)
├── root                 <-- Homedir del superusuario
├── sbin                 <-- Aplicaciones de administración
├── tmp                  <-- Directorio para archivos temporarios
├── usr                  <-- Varios directorios del sistema
│   ├── bin              <-- Aplicaciones de usuarios
│   ├── lib              <-- Más bibliotecas
│   ├── libexec
│   ├── local            <-- Instalación de aplicaciones locales
│   ├── sbin             <-- Más aplicaciones de administración
│   ├── share            <-- Archivos compartidos por varias aplicaciones
│   └── src              <-- Fuentes
└── var                  <-- Directorio de archivos de aplicaciones que están ejecutando
    ├── log              <-- LOGS del sistema
    ├── run              <-- archivos de control y/o comunicación de aplicaciones o servicios
    ├── spool            <-- archivos temporarios de aplicaciones (por ej. servicio de email)
    └── www              <-- archivos de un servicio web

Ejercicio:

 sudo tree -dL 1 /
 sudo tree -dL 2 /

Vamos a comentar brevemente algunos de esos directorios y cuál es su función:

Archivos de programas: /bin, /usr/bin, /sbin, /usr/sbin

Cuando corremos un programa o comando desde el shell ¿Cómo sabe Linux donde se encuentra ese programa? Podría estar cualquier rincón del filesystem.

Bash usar una variable de environment, PATH, para definir la lista de directorios donde va a buscar los programas.

Ejercicio:

echo $PATH

Valores típicos para PATH:

/bin:/usr/bin:/usr/local/bin

El valor de la variable PATH es una lista de directorios, separados por :. Linux buscar el programa que queremos ejecutar en esa lista, en el orden que aparece la lista (ojo con el orden en que se hace la búsqueda). El valor de PATH se puede cambiar. Supongamos que queremos incluir el directorio /home/linux/bin en nuestro PATH, podemos hacer esto:

export PATH=$PATH:/home/linux/bin

o esto otro:

export PATH=/home/linux/bin:$PATH

Así que podríamos escribir un programa que tenga el mismo nombre que un comando del sistema y dependiendo de en qué orden definamos el valor de PATH se usa un programa o el otro. Ojo con eso.

En general /bin, /usr/bin y /usr/local/bin aloja los programas del sistema que son usados por los usuarios sin privilegios. /sbin y /usr/sbin aloja los programas que usa root (o algún usuario con privilegios limitados). En /usr/local se suelen instalar programas que no vienen con la distribución de Linux o versiones diferentes de programas que vienen con la distribución usada.

En realidad nada impide instalar programas en cualquier lado, pero es recomendable adecuarse a utilizar los directorios habituales o tradicionales.

Dispositivos: /dev

En ese directorio se encuentran todos los dispositivos del sistema, particularmente los dispositivos de hardware (dispositivos de red, discos, puertos seriales, etc.), aunque también hay de software (pseudoterminales, generación de números aleatorios (random/urandom), null, etc.).

Un dispositivo muy usado es /dev/null, cuando un programa genera salida de datos pero no nos interesa conservar esos datos, podemos redirigir la salida a /dev/null y no ocupan lugar.

programa >/dev/null

Configuración del sistema: /etc

Debajo de /etc se encuentran habitualmente todos los directorios y archivos de configuración de todo el sistema y los servicios que corran bajo Linux.

En particular vamos a mencionar estos archivos: /etc/groups, /etc/passwd y /etc/shadow, donde se encuentra la información de todos los usuarios y grupos del sistema. Los dos primeros se pueden leer, pero el último sólo puede ser leído y modificado por root.

Home directories de usuarios: /home y /root

Debajo de /home se suelen encontrar los directorios de los usuarios del sistema. Por razones de seguridad, el directorio del superusuario se encuentra en /root.

Directorio de los procesos: /proc

Siguiendo con el paradigma todo es un archivo, los propios procesos que corren bajo Linux tienen su representación en el filesystem, debajo del directorio /proc.

Archivos variables del sistema: /var

Una vez que tenemos instalado y configurado un equipo con Linux, es poco habitual que los archivos del sistema sean modificados. Pero muchas aplicaciones o servicios que corren en el sistema requieren crear, borrar o modificar archivos que cambian constantemente. Tradicionalmente estos archivos se alojan en el árbol de directorios debajo de /var.

Ejemplos:

/var/spool/mail     <-- archivos temporarios de un servicio de email
/var/lib/mysql      <-- alojamiento de las bases de datos de un gestor MySQL
/var/www            <-- archivos de contenido de un servidor web

Cabe destacar el directorio /var/log, pues allí suelen ir a parar todos los mensajes de los servicios que corren bajo Linux. Así que si uno quiere saber si algún servicio está corriendo bien o hay algún problema, el lugar donde mirar es en ese directorio. Allí suelen aparecer todos los mensajes del sistema, particularmente si hay problemas o pueden ser simplemente mensajes de registros de actividad (cada vez que un usuario se loguea al sistema, cada vez que se recibe o envía un email o se accede a una página web, etc.).

Ejercicio:

ls -l /var

Directorio corriente o directorio de trabajo

Cuando estamos trabajando dentro del shell, siempre estamos “parados” en algún directorio. Ese directorio es conocido como directorio corriente o directorio de trabajo.

Cuando ingresamos al sistema, el directorio de trabajo es nuestro homedir, por ej. /home/linux.

Para saber donde estamos “parados”, podemos correr el comando: pwd (present working directory)

pwd
/home/linux

Es posible cambiarse de directorio, usando el comando cd (change directory), ya sea haciendo referencia absoluta o relativa al directorio (path) donde queramos cambiarnos.

Para listar el contenido del directorio donde estamos parados, podemos correr el comando

ls -la
total 532
drwxr-x---  70 linux  users   4096 Sep 16 12:00  .
drwxr-xr-x   4 root   root    4096 Aug  2  2018  ..
drwxr-x---  58 linux  users  12288 Sep 16 10:12  Documents
-rw-r--r--   1 linux  users    146 Aug 23 08:26  archivo.txt
-rwxr-xr--   1 linux  wheel    146 Aug 23 08:26  script.sh
-rwxrwxrwx   1 linux  wheel    146 Aug 23 08:26  archivo2.txt

Los directorios . y .. son dos directorios especiales: hacen respectivamente referencia al directorio listado y al directorio padre.

Són muy útiles cuando hacemos referencia relativa de archivos y directorios

Por ejemplo, si estamos en el directorio donde se encuentra script.sh, pero ese directorio no se encuentra en el PATH, la manera de pedir a bash que ejecute ese archivo es mediante una referencia relativa: ./script.sh, en lugar de la referencia absoluta: /home/linux/script.sh

Si queremos pasar al directorio Documents, podríamos hacer de dos maneras

cd Documents               (por referencia relativa)
cd /home/linux/Documents   (por referencia absoluta)

Si estamos en nuestro homedir y queremos pasar a /home, podemos usar cd de las siguientes maneras:

cd /home

o

cd ..

La referencia absoluta nos asegura inequívocamente el destino, pues le damos el path completo. La referencia relativa suele ser más cómoda y compacta, pero depende de donde estemos “parados”.

Si queremos volver a nuestro homedir, alcanza con ejecutar el comando cd solo:

cd

Una forma compacta de hacer referencia a nuestro homedir es usar el tilde: ~

Ejemplo:

cd /home/linux/Documents

es equivalente a

cd ~/Documents

Crear/remover directorios y archivos

Crear un directorio:

mkdir path

Como siempre, el path puede ser absoluto o relativo, y es la secuencia de nombres de directorios, subdirectorios y archivos que permiten determinar la ubicación del recurso al que queremos acceder.

Ejemplo:

mkdir dir1

genera un el directorio dir1 debajo del directorio corriente

mkdir /tmp/dir1

genera el directorio dir1 debajo del directorio /tmp/

mkdir ../dir1

genera el directorio dir1 en el directorio padre del directorio corriente

Remover un directorio:

rmdir path       

Ojo: para que rmdir funcione el directorio debe estar vacío

Alternativa:

rm -r path

OJO: en este caso se borra todo lo que haya debajo de ese directorio… usar con precaución

Crear un archivo:

Además de poder crear/modificar archivos usando redireccionamiento, como vimos en la clase pasada, o usando algún editor de texto o simplemente copiando o bajando un archivo de otro lado, también podemos usar los siguientes comandos para crear archivos en el filesystem:

touch path
> path

Ojo: touch es para actualizar las fechas de creación/acceso/modificación de un archivo. Si el archivo no existe, entonces lo crea.

Remover un archivo:

rm path

Mover un archivo o directorio de un lugar a otros en el filesystem:

mv path_origen  path_destino

Cambiar de nombre a un directorio o archivo:

rename path newpath

Dependiendo de cómo se lo use, mv también tiene el efecto de renombrar un archivo.

Permisos, Usuarios y Grupos

La posibilidad de acceder a un recurso o poder correr un programa dependerá de los permisos que ese recurso o programa tenga.

Dijimos que básicamente todo recurso en Linux era accesible a través del path (conjunto de directorios y subdirectorios) que define su ubicación.

Un usuario podrá acceder a un cierto directorio o archivo, o podrá correr un cierto programa, o acceder a un cierto dispositivo, dependiendo de los permisos que ese recurso tenga (o más precisamente, los permisos de todo el path).

Podremos listar un directorio del sistema:

ls -la /dir1/subdir2

O ver el contenido de un archivo:

cat /dir1/archivo.txt

siempre y cuando los permisos de acceso y/o lectura sean los adecuados… en todo el path.

Permisos

Pero defecto, todo directorio o archivo del sistema pertenece a un usuario y a un grupo. A su vez, un usuario puede pertenecer a uno o más grupos.

El sistema de permisos de Linux define 3 niveles: usuario, grupo y otros

A su vez, para cada uno de estos niveles, se puede definir un permiso de lectura, escritura y ejecución (o acceso en caso de directorios), que se etiquetan: rwx

Así que tenemos en principio 3 posibles permisos (rwx) para cada uno de los 3 niveles (usuario, grupo, otro).

Si listamos nuestro homedir (/home/linux), podemos ver de qué manera se representan estos permisos:

ls -la
total 532
drwxr-x---  70 linux  users   4096 Sep 16 12:00  .
drwxr-xr-x   4 root   root    4096 Aug  2  2018  ..
drwxr-x---  58 linux  users  12288 Sep 16 10:12  Documents
-rw-r--r--   1 linux  users    146 Aug 23 08:26  archivo.txt
-rwxr-xr--   1 linux  wheel    146 Aug 23 08:26  script.sh
-rwxrwxrwx   1 linux  wheel    146 Aug 23 08:26  archivo2.txt

Cómo fijamos o cambiamos los permisos

Dijimos que lo que podamos hacer con un directorio o un archivo estará determinado por los permisos (rwx) y qué usuario/grupo sea dueño de ese directorio o archivo.

Cambiar el dueño de un archivo

Con chown puedo cambiar el usuario o grupo al que un cierto recurso pertenece. Con chgrp sólo cambio el grupo.

chown usuario  path
chown usuario:grupo path
chown -R usuario:grupo path
chgrp group path

Cambiar permisos rwx

Dos modalidades: usando valores octales o haciendo referencia explícita a permisos para usuario, grupo u otros.

Notación octal

rwx puede representarse con bits. Si el valor del bit es 1, el permiso está habilitado, si el valor del bit es 0, no está habilitado.

Así entonces correspondería a 3 ceros: 000, r– correspondería a 100, rw- corresponde a 110, etc.

Con 3 bits se pueden representar los números del 0 al 7, por eso 3 bits corresponde a una notación octal (números en base 8):

 Permiso      bits     octal 
  - - -       000        0
  - - x       001        1
  - w -       010        2
  r - -       100        4

todas las posibles combinaciones surgen de sumar 0. 1, 2 y 4

Por ejemplo: rwx equivale a 111 que la suma 1+2+4=7. rw- equivale a 110 que es la suma de 4+2=6, r-x equivale a 101 que es la suma de 1+4=5, etc.

Estos valores octales los declaramos en ternas (usuario, grupo, otros).

ls -l archivo2.txt
-rwxrwxrwx   1 linux  wheel    146 Aug 23 08:26  archivo2.txt

archivo2.txt tiene permisos para ser leído, modificado y ejecutado por todo el mundo. Si queremos restringir esos permisos, por ejemplo, para que sólo sea modificado por el usuario linux y leído por el grupo wheel y que el resto de los usuarios no tenga acceso al mismo:

chmod 640 archivo2.txt
ls -l archivo2.txt
-rw-r-----   1 linux  wheel    146 Aug 23 08:26  archivo2.txt

La ventaja de la notación octal es que son una terna de dígitos podemos definir todos los permisos de un recurso.

Notación más sencilla:

Podemos definir o determinar los permisos de un recurso determinado, haciendo referencia a usuario/grupo/otros (ugo) y los permisos explícitos para cada nivel:

Por ej.: Sea un archivo script.sh que inicialmente tiene estos permisos:

ls -l script.sh
-rw-rw-rw-   1 linux  wheel    146 Aug 23 08:26  script.sh

tal como están los permisos, en principio todos pueden leer y modificar el archivo, pero no tienen permiso para ejecutar el script.

Supongamos que queremos modificar los permisos para que el dueño pueda modificarlo y ejecutarlo, el grupo sólo pueda ejecutarlo y el resto no pueda hacer nada con ese archivo.

chown u=rwx,g=rx,o= script.sh

La notación es más larga, pero más sencilla de recordar. Ahora al listar comprobamos cómo quedaron los permisos:

-rwxr-x---   1 linux  wheel    146 Aug 23 08:26  script.sh

Nótese que para asegurarse que el resto del mundo (others) pierda los permisos, hubo que explícitamente declarar o=, de lo contrario esos permisos quedarían sin cambiar.

IMPORTANTE: OJO CON LOS PERMISOS… no solamente importa quién es el dueño (usuario:grupo) y cuales son los permisos de un archivo o directorio concreto, sino también los permisos que tengan los directorios que hay que atravesar para llegar a ese recurso.

Por ej., si un archivo tiene permisos de lectura o ejecución para un usuario, grupo o el resto de los usuarios, pero uno o más directorios que hay que atravesar para llegar a ese archivo no tiene al menos permiso de acceso (x) para ese usuario, grupo o para el resto de los usuarios, entonces ese recurso no es accesible.

Si un archivo tiene permiso de escritura, pero el directorio donde se encuentra no me da permiso de escritura, entonces no puedo modificar ese archivo. Porque modificar un archivo no solamente implica cambiar el contenido del archivo, sino también actualizar la información del directorio donde ese archivo se encuentra.

Para que un archivo sea ejecutable, debe tener no solamente permiso de ejecución (x) sino también de lectura ®, o sea que al menos debe tener los permisos r-x.

Un directorio no necesariamente tiene que tener permiso de lectura para poder acceder y/o modificar un archivo que se encuentre en su interior. Alcanza con que tenga permiso de acceso y eventualmente escritura.

Resumiendo: El tema de los permisos es sutil

Temas avanzados: ACL

ACL (access control lists): con el sistema de permisos de Linux se puede ir muy lejos, pero ciertamente no cubre todas las posibilidades/necesidades. Existen extensiones al sistema básico de permisos de Linux, como ACL, que extienden los permisos para incluir permisos para más usuarios/grupos para cada recurso del filesystem. Pero es más complejo de instalar y utilizar, quedará para más adelante… Por ahora alcanza con que sepan que existe.

Lo recomendable, para no complicarse la vida, es tratar de arreglarse con los permisos básicos de Linux.

Wildcards

Hasta ahora vimos cómo usar comandos sobre un archivo o un directorio. Pero en muchas ocasiones en conveniente operar sobre varios archivos o directoros simultáneamente. Para eso el shell nos ofrece el uso de wildcards.

Un wildcard es uno o más caracteres especiales que permiten hacer referencia a uno o más recursos del filesystem.

Los wildcards que podemos usar en bash son los siguientes:

  • *: vale por uno o más caracteres
  • ?: vale por un caracter
  • []: vale por un conjunto o rango de caracteres

Para ejemplificar cómo funcionan los wildcards, vamos a trabajar con algunos archivos:

Sean los siguientes archivos en el directorio:

pepe-1.log  pepe_1.txt  pepe-1.txt  pepe-2.log  pepe-2.txt  pepe-3.txt 

Vemos que los nombres de los archivos comparten elementos en común. todos tienene el prefijo pepe, seguido de un guión o guión bajo, un número y luego una extensión .txt o .log.

Podemos usar directentes combinaciones de wildcards para hacer referencia a diferentes subconjuntos de archivos y aplicar a esos subconjuntos diferentes comandos (por ej. cp, mv, rm, etc.)

Vamos a ejemplificar algunos usos de los wildcards:

Asterísco

Ejemplo:

ls *
pepe-1.txt pepe-1.log pepe-2.txt pepe-2.log pepe_1.txt pepe-3.txt
ls *txt
pepe-1.txt pepe-2.txt pepe_1.txt pepe-3.txt
ls *1*
pepe-1.txt pepe-1.log pepe_1.txt

ls *-1*
pepe-1.txt pepe-1.log
Signo de interrogación

Ejemplo:

ls pepe??.log
pepe-1.log pepe-2.log 

ls *1.???
pepe-1.txt pepe-1.log pepe_1.txt 
ls pepe-?.txt
pepe-1.txt pepe-2.txt pepe-3.txt
Conjuntos o rangos

Ejemplo:

ls pepe-[12].txt
pepe-1.txt pepe-2.txt 

Si entre dos caracteres ponemos un guión, eso vale por un rango de caracteres:

ls *[1-3].txt
pepe_1.txt  pepe-1.txt  pepe-2.txt  pepe-3.txt

Cuando se antepone un '^' en el grupo o rango de caracteres, se niega al conjunto:

ls *[^12].txt
pepe-3.txt

Para considerar al guión dentro del grupo de caracteres, tiene que aparecer primero:

ls *[-_]1.txt
pepe_1.txt pepe-1.txt

Estos ejemplos, que vimos para el comando ls, pueden aplicarse para cualquier comando. No es algo que dependa del comando en particular, sino que es la notación que maneja el propio bash.

En los hechos lo que bash hace, antes de ejecutar el comando, es expandir los wildcards, vale decir generar el listado de posibilidades que determinan los wildcards que estemos usando y sustituirlo en la linea de comando que le pasa al comando que queremos correr.

Ejemplo: probar

echo *
echo *t
echo *3*
echo *[13]*t

Links: soft y hard

Dijimos que en Unix/Linux, todo recurso del filesystem es un archivo. Los discos son dispositivos de almacenamiento de bloques de datos. Por conveniencia, el sistema operativo nos muestra esos bloques de datos como archivos o directorios. Los archivos contienen datos, los directorios contienen listados de archivos u otros directorios, pero no son más que archivos cuyo contenido es interpretado de manera especial: son índices de archivos y directorios.

En un índice es perfectamente posible hacer más de una referencia a un mismo objeto. Esto quiere decir que no hay inconveniente en que una referencia a un archivo de datos o un directorio aparezca más de una vez en el filesystem.

Lo normal que es que todo archivo o directorio tenga al menos una referencia en un directorio, de lo contrario no hay manera de llegar a ese recurso. Pero nada impide que haya más de una referencia a un mismo recurso.

Cada entrada a un recurso en un directorio es un link a ese recurso y tiene al menos un nombre que lo identifica.

Hay dos tipos de links en los filesystems de Linux: hard y soft links

Un hard link es una referencia directa a un recurso, que aparece listado en un directorio. Un soft link es un archivo que hacer referencia a otro recurso en el filesystem.

Un hard link es una referencia directa. Un soft link es una referencia indirecta.

El comando ls nos puede mostrar cuantos links tiene un determinado recurso

Por ejemplo:

total 612
drwxr-xr-x 4 linux linux   4096 Sep 22 08:53 .
drwxr-xr-x 7 linux linux   4096 Sep 22 08:35 ..
drwxr-xr-x 2 linux linux   4096 Sep 22 08:53 dir1
drwxr-xr-x 2 linux linux   4096 Sep 22 08:53 dir2
-rw-r--r-- 2 linux linux     13 Sep 22 08:47 francisco
lrwxrwxrwx 1 linux linux      6 Sep 22 08:48 panchito -> pancho
-rw-r--r-- 2 linux linux     13 Sep 22 08:47 pancho
-rwxr-x--- 1 linux linux     54 Sep 22 10:34 pepe
-rw-r--r-- 1 linux linux     44 Sep 22 08:42 pepe0.txt
-rw-r--r-- 1 linux linux     11 Sep 22 08:42 pepe1.txt
-rw-r--r-- 1 linux linux 181489 Sep 22 08:39 pepe.odt
-rw-r--r-- 1 linux linux 235506 Sep 22 08:40 pepe.pdf
-rw-r----- 1 linux linux 171955 Sep 22 08:40 pepe.png

Luego de la columna de permisos, el número que aparece es la cantidad de hard links que tiene ese recurso. Luego aparcen los nombres de usuario y grupo que son dueños de ese recurso, luego aparece el tamaño (en bytes) del recurso, seguido por la fecha y el nombre del recurso.

Podemos comprobar que hay dos archivos: francisco y pancho que tienen 2 hard links y el mismo tamaño. Si hacemos un cat del contenido de esos archivos podremos comprobar que tienen el mismo contenido. si modificamos uno de ellos el otro también se modifica y si ejecutamos el comando md5sum también obtenemos el mismo valor de hash, por lo tanto ambos archivos en realidad son referencias al mismo bloque de datos del filesystem. Son dos hard links a los mismos datos.

Los demás archivos tienen un sólo hard link.

Pregunta: ¿Por qué los directorios tienen más de un hard link?

También comprobamos que hay un archivo particular, llamado panchito que “apunta” a pancho.

Ese es un ejemplo de un soft link. Como dijimos un soft link es un archivo especial cuyo contenido es una referencia a otro recurso (archivo o directorio). Por eso es una referencia indirecta.

Así como los directorios se diferencian de los archivos porque en la primer columna del listado largo aparece una letra d, los soft links se distinguen porque en la primer columna aparece la letra l.

Restricciones

Como un hard link en realidad es una referencia directa a un bloque de datos en un disco duro, los hard links están limitados al filesystem de ese disco duro y no es posible tener un hard link a un recurso que se encuentre en otro disco duro.

Los soft links no tienen esa limitación, pues en realidad son referencias indirectas.

Así que la posibilidad de crear un nuevo link (hard o soft) depende de si ese nuevo link lo creamos en el mismo disco duro o no.

Evidentemente al crear un directorio o un archivo, lo que estamos creando es un hard link a un bloque de datos del filesystem. Pero dijimos que podemos crear más de un link. Veamos cómo:

Hard link:

ln recurso_existente recurso_nuevo

Soft link:

ln -s recurso_existente recurso_nuevo

La opción -s define que el link que estamos creando es soft. Si no usamos esa opción, lo que creamos en un hard link.

Nombres, extensiones y tipos de archivo: el hábito no hace al monje

En Linux el nombre de un recurso puede ser cualqueir cosa. En particular no es obligatorio que los nombres de archivos tengan extensión (punto algo), pero se acostumbra poner extensiones, más por un tema de comodidad y costubre que otra cosa.

Es así que en particular la mayoría de los programas o comandos del sistema no tienen extensión alguna (no es como en Windows que siempre tienen una extensión .exe o .com).

Pero es habitual que los archivos de datos tengan alguna extensión que resulte práctica para el usuario, aunque no es obligatorio.

Si realmente queremos saber qué es un archivo, lo mejor es usar el comando file. Por ejemplo:

file *

dir1:      directory
dir2:      directory
francisco: ASCII text
panchito:  symbolic link to pancho
pancho:    ASCII text
pepe:      Python script, ASCII text executable
pepe0.txt: ASCII text
pepe1.txt: UTF-8 Unicode text
pepe.odt:  OpenDocument Text
pepe.pdf:  PDF document, version 1.4
pepe.png:  PNG image data, 1024 x 1024, 8-bit/color RGBA, non-interlaced

Que un archivo tenga una determinada extensión no lo convierte en un archivo de ese “tipo”

Ejemplo:

cp pepe1.txt pepe1.jpg
file pepe1*
pepe1.jpg: UTF-8 Unicode text
pepe1.txt: UTF-8 Unicode text

El archivo pepe1.jpg es una copia de pepe1.txt que es un simple archivo de texto y no una imagen.