1.8. Gestión básica de ficheros
1.8.2. Metacaracteres y operadores
Ya sea que estéis listando, moviendo, copiando, eliminando o realizando cualquier otra acción con archivos en tu sistema Gnu/Linux, existen ciertos caracteres especiales, denominados metacaracteres y operadores, que os ayudarán a trabajar con archivos de manera más eficiente. Los metacaracteres pueden ayudar a hacer coincidir uno o varios archivos sin tener que escribir completamente cada nombre de archivo. Los operadores te permiten dirigir información de un comando o archivo a otro comando o archivo.
Por otra parte, también hay que introducir ciertos mecanismos de citación. Con ejemplos, será más fácil de entender:
Carácter escape
Una barra invertida no citada «\» es el carácter de escape de bash: preserva el valor literal del siguiente carácter que sigue, con la excepción de la nueva línea.
$ echo variable; argumento
variable argumento: command not found
# Si se escribe «\;»
te ayuda a usar «;»
como un carácter normal
$ echo variable \; argumento
variable ; argumento
# Un ejemplo más sutil. El objetivo es crear un solo fichero que se llame mi fichero.txt
$ touch mi fichero.txt
$ ls mi*txt
ls: cannot access mi*txt': No such file or directory
$ rm fichero.txt m
# Con el carácter escape se genera un único fichero
$ touch mi\ fichero.txt
$ ls mi*txt
'mi fichero.txt'
$ rm mi\ fichero.txt
Comillas sencillas
Encerrar caracteres en comillas simples (')
preserva el valor literal de cada carácter dentro de las comillas. Una comilla simple no puede darse entre comillas simples, incluso cuando esté precedida por una barra invertida. Y ningún carácter es especial dentro de las cadenas entre comillas simples. Ejemplos:
$ echo 'variable; argumento'
variable; argumento
# Se pueden colocar cadenas representadas por diferentes mecanismos de citación una al lado de la otra para concatenarlas. Otro ejemplo:
# concatenación of 4 strings # 1: '@comandos = ' # 2: \' # 3: 'sort and grep' # 4: \'
$ echo '@comandos = '\' sort and grep'\'
@comandos = 'sort and grep\
Comillas dobles
Encerrar caracteres en comillas dobles (")
preserva el valor literal de todos los caracteres dentro de las comillas, con la excepción de $
, `, ,
y, cuando la expansión de historia está habilitada, !
. Aquí hay un ejemplo que muestra la interpolación de variables dentro de comillas dobles:
$ qty='5'
# Ningún carácter es especial dentro de las comillas simples
$ echo 'Desde principio de año, he ejecutado $qty GWAS'
Desde principio de año, he ejecutado $qty GWAS
# Un uso típico de las comillas dobles es habilitar la interpolación de variables
$ echo "Desde principio de año, he ejecutado $qty GWAS"
Desde principio de año, he ejecutado 5 GWAS
# A menos que quieras específicamente que la shell interprete el contenido de una variable, siempre debes entrecomillar la variable para evitar problemas debido a la presencia de metacaracteres de la Shell
$ f='segundo fichero.txt'
# Sería lo mismo que: echo 'pec informe' > segundo fichero.txt
$ echo 'pec informe' > $f
bash: $f: ambiguous redirect
# Sería lo mismo que: echo 'pec informe' > 'segundo fichero.txt'
$ echo 'pec informe' > "$f"
$ cat "$f"
pec informe
$ rm "$f"
Ahora sí que nos introducimos más profundamente en la definición de metacaracteres y operadores.
Metacaracteres
Para ahorrar algunas pulsaciones de teclas y permitiros referencias fáciles a un grupo de archivos, la shell bash os permite usar metacaracteres. Aquí hay algunos metacaracteres útiles para hacer coincidir nombres de archivos. En la tabla 4 se describen los más habituales.
Tabla 4. Metacaracteres de fichero.
Comodín | Descripción |
? | Coincidir un carácter, cualquier carácter |
* | Coincidir cualquier cantidad de caracteres |
[….] | Coincidir cualquiera de los caracteres entre los corchetes, que pueden incluir un rango de letras o números separados por un guion |
[! ….] | No coincidir con ninguno de los caracteres entre los corchetes, que pueden incluir un rango de letras o números separados por un guion |
Probad algunos de estos metacaracteres de coincidencia de archivos yendo primero a un directorio vacío (como el directorio de prueba descrito en la sección anterior) y creando algunos archivos vacíos. El comando touch
crea archivos vacíos. Las líneas de comandos que siguen le muestran cómo utilizar metacaracteres de shell con el comando ls
para coincidir con nombres de archivo. Cualquier otro comando también funciona.
$ touch Transcriptomics Proteomics Epigenomics Metagenomics Pharmacogenomics
$ ls P*
Pharmacogenomics Proteomics
# Se imprime cualquier archivo que comience con P
$ ls P*t*
Proteomics
# Se imprime cualquier archivo que comience con P y contenga la t
$ ls [EM]*
Epigenomics Metagenomics
# Se imprime cualquier archivo que comience por E or M
$ ls [P-Z]*
Pharmacogenomics Proteomics Transcriptomics
# Se imprimen todos los nombres de archivo que comienzan con una letra entre P y Z
$ ls ???genomics
Epigenomics
# Se imprime cualquier archivo de 11 caracteres que termine con la cadena genomics
Metacaracteres de redireccionamiento de archivos
Los comandos reciben datos desde la entrada estándar y los envían a la salida estándar. Utilizando pipes (en castellano, tuberías) se puede dirigir la salida estándar de un comando a la entrada estándar de otro. Con archivos, se puede usar el signo menor que (<
) y mayor que (>
) para dirigir datos hacia y desde archivos. En la tabla 5 se recogen los caracteres de redireccionamiento de archivos:
Tabla 5. Metacaracteres de redireccionamiento.
Comodín | Descripción |
< |
Dirige el contenido de un archivo al comando. En la mayoría de los casos, esta es la acción predeterminada esperada por el comando y el uso del carácter es opcional; usar «less seq.fa » es lo mismo que «less < seq.fa » |
> |
Dirige la salida estándar de un comando a un archivo. Si el archivo existe, el contenido de ese archivo se sobrescribe |
2> |
Dirige el error estándar (mensajes de error) al archivo |
&> |
Dirige tanto la salida estándar como el error estándar al archivo |
>> |
Dirige la salida de un comando a un archivo, agregando la salida al final del archivo existente |
Las siguientes líneas son ejemplos realizados mediante líneas de comando donde la información se dirige hacia y desde archivos:
$ mail root < ~/.bashrc
$ man chown | col -b > /tmp/chown
$ echo "Estoy practicando los ejercicios de HIB en $(date)" >> ~/testHIB/testimonio
En el primer ejemplo, el contenido del archivo .bashrc en el directorio de inicio se envía en un mensaje de correo al usuario root de la máquina Gnu/Linux. La segunda línea de comando formatea la página del manual de chown (utilizando el comando man
), elimina los espacios en blanco adicionales (col -b
) y envía la salida al archivo /tmp/chown (borrando el archivo /tmp/chown anterior, si existiera). El comando final genera un fichero de texto que se visualiza con el comando cat
:
$cat testHIB/testimonio
Estoy practicando los ejercicios de HIB en Wed 19 Apr 19:08:04 CEST 2023
Otro tipo de redireccionamiento permite escribir texto que se puede emplear como entrada estándar para un comando. Los documentos implican, aquí, ingresar dos caracteres de menor (<<
) después de un comando seguido de una palabra. Todo lo que escribáis después de esa palabra se tomará como entrada del usuario hasta que se repita la palabra en una línea aparte.
$ mail student Josep Joan Guerau Bego << mensaje
> Os recuerdo que hay que realizar todos los ejercicios > propuestos para entender la asignatura. > > equipo HIB > mensaje $
$
Este ejemplo envía un mensaje de correo a los usuarios student, Josep, Joan, Guerau y Bego. El texto introducido entre <<mensaje>> y <<mensaje>> se convierte en el contenido del mensaje.
Caracteres de expansión de llaves
Al usar llaves ({}
), podéis expandir un conjunto de caracteres en los nombres de archivo, nombres de directorios u otros argumentos que des a los comandos. Por ejemplo, si queréis crear el conjunto de archivos desde sequence1 hasta sequence7, podéis hacerlo de la siguiente manera:
$ touch sequence{1,2,3,4,5,6,7}
$ ls
sequence1 sequence2 sequence3 sequence4 sequence5 sequence6 sequence7
$ rm sequence?
Los elementos que se expanden no tienen que ser números, ni siquiera dígitos únicos; podríais usar rangos de números o dígitos. También podríais utilizar cualquier cadena de caracteres, siempre y cuando se separen con comas. Ejemplo:
$ touch sequence{1..4}-{human,drosophila}
$ ls
sequence1-drosophila sequence2-drosophila sequence3-drosophila sequence4-drosophila sequence1-human sequence2-human sequence3-human sequence4-human
$ rm sequence*
Permisos de archivos y la propiedad
Después de trabajar con Gnu/Linux durante un tiempo, es casi seguro que obtendréis un mensaje de permiso denegado. Los permisos asociados a archivos y directorios en Gnu/Linux fueron diseñados para evitar que los usuarios accedan a los archivos privados de otros usuarios y para proteger los archivos importantes del sistema. Los nueve bits asignados a cada archivo para los permisos definen el acceso que vosotros y otros tienen a tu archivo. Los bits de permiso para un archivo regular aparecen como -rwxrwxrwx
. Esos bits se usan para definir quién puede leer, escribir o ejecutar el archivo.
De los permisos de nueve bits, los primeros tres bits se aplican al permiso del propietario, los siguientes tres se aplican al grupo asignado al archivo y los últimos tres se aplican a todos los demás. La r
significa lectura, la w
significa escritura y la x
significa permisos de ejecución. Si aparece un guion en lugar de la letra, significa que ese permiso está desactivado para ese bit asociado de lectura, escritura o ejecución.
Podéis ver los permisos de cualquier archivo o directorio escribiendo el comando ls -ld
. El archivo o directorio nombrado aparece como se muestra en este ejemplo:
$ ls -ld testHIB testHIB/testimonio
-rw-rw-r-- 1 student student 73 Apr 19 19:08 testHIB/testimonio drwxr-xr-x 2 student student 4096 Apr 19 19:27 testHIB
La primera línea muestra que el archivo testimonio tiene permiso de lectura y escritura para el propietario y el grupo. Todos los demás usuarios tienen permiso de lectura, lo que significa que pueden ver el archivo, pero no pueden cambiar su contenido ni eliminarlo. La segunda línea muestra el directorio testHIB (indicado por la letra d antes de los bits de permiso). El propietario tiene permisos de lectura, escritura y ejecución, mientras que el grupo y otros usuarios solo tienen permisos de lectura y ejecución. Como resultado, el propietario puede agregar, cambiar o eliminar archivos en ese directorio, y todos los demás solo pueden leer el contenido, cambiar a ese directorio y listar el contenido del directorio.
Si sois propietarios de un archivo, podéis usar el comando chmod
para cambiar los permisos como deseéis. En un método para hacer esto, a cada permiso (lectura, escritura y ejecución) se le asigna un número: r = 4, w = 2 y x = 1, y utiliza el número total de cada conjunto para establecer el permiso. Por ejemplo, para hacer que los permisos estén completamente abiertos para vosotros como propietarios, estableceríais el primer número en 7 (4 + 2 + 1), y luego daríais al grupo y a otros permisos de solo lectura, estableciendo ambos el segundo y el tercer número en 4 (4 + 0 + 0), de modo que el número final sea 744. Cualquier combinación de permisos puede resultar desde 0 (sin permiso) hasta 7 (permiso completo).
Aquí hay algunos ejemplos de cómo cambiar el permiso de un archivo (llamado archivo) y de qué permiso resultaría:
# La ejecución del comando chmod da como resultado este permiso: rwxrwxrwx
$ chmod 777 archivo
# La ejecución del comando chmod da como resultado este permiso: rwxr-xr-x
$ chmod 755 archivo
# La ejecución del comando chmod da como resultado este permiso: rw-r--r--
$ chmod 644 archivo rw-r--r-
# La ejecución del comando chmod da como resultado este permiso: ---------
$ chmod 000 archivo
El comando chmod
también se puede usar de manera recursiva. Por ejemplo, supongamos que deseáis dar una estructura de directorios completa con permiso 755 (rwxr-xr-x
), comenzando en el directorio $HOME/testHIB
. Para hacer eso, se podría usar la opción -R
(recursiva), como sigue:
$ chmod -R 755 $HOME/testHIB
Todos los archivos y directorios debajo, e incluyendo el directorio Work en su directorio de inicio, tendrán permisos 755 establecidos. Debido a que el enfoque de los números para establecer cambios de permiso, con todos los bits de permiso a la vez, generan confusión, es más común usar letras para cambiar recursivamente los bits de permiso en un gran conjunto de archivos.
También podéis activar y desactivar los permisos de un archivo utilizando los signos más (+
) y menos (-
), respectivamente, junto con letras para indicar qué cambios y para quién. Empleando letras, para cada archivo, podéis cambiar los permisos para el usuario (u
), el grupo (g
), otros (o
) y todos los usuarios (a
). Lo que cambiaríais incluye los bits de lectura (r), escritura (w
) y ejecución (x
). Por ejemplo, comenzáis con un archivo que tenga todos los permisos abiertos (rwxrwxrwx
). Ejecutáis los siguientes comandos chmod
utilizando opciones con signo menos. Los permisos resultantes se muestran a la derecha de cada comando:
# La ejecución del comando chmod resulta en este permiso: r-xr-xr-x
$ chmod a-w archivo
# La ejecución del comando chmod resulta en este permiso: rwxrwxrw-
$ chmod o-x archivo
# La ejecución del comando chmod resulta en este permiso: rwx------
$ chmod go-rwx archivo
Asimismo, los siguientes ejemplos comienzan con todos los permisos cerrados (---------
). El signo más se utiliza con chmod
para activar los permisos:
# La ejecución del comando chmod resulta en este permiso: rw-------
$ chmod u+rw archivos
# La ejecución del comando chmod resulta en este permiso: --x--x--x
$ chmod a+x archivos
# La ejecución del comando chmod resulta en este permiso: r-xr-x---
$ chmod ug+rx archivos
El uso de letras para cambiar los permisos de manera recursiva con chmod
generalmente funciona mejor que usar números, porque se pueden cambiar los bits selectivamente, en lugar de cambiar todos los bits de permiso a la vez.