La sintaxis a*
y la *a*
implementa el shell, no el ls
comando.
Cuando escribes
ls a*
en su shell del sistema, la cáscara se expande a*
a una lista de todos los archivos existentes en el directorio actual cuyos nombres comienzan con a
. Por ejemplo, podría expandirse a*
a la secuencia a1 a2 a3
y pasarlos como argumentos a ls
. El ls
comando en sí mismo nunca ve al *
personaje; sólo ve las tres argumentos a1
, a2
y a3
.
Para propósitos de expansión de comodines, "archivos" se refiere a todas las entidades en el directorio actual. Por ejemplo, a1
podría ser un archivo normal, a2
podría ser un directorio y a3
podría ser un enlace simbólico. Todos tienen entradas de directorio, y a la expansión comodín del shell no le importa a qué tipo de entidad se refieren esas entradas.
Prácticamente todos los shells con los que es probable que te encuentres (bash, sh, ksh, zsh, csh, tcsh, ...) implementan comodines. Los detalles pueden variar, pero la sintaxis básica de *
coincidencia de cero o más caracteres y la ?
coincidencia de cualquier carácter individual es razonablemente consistente.
Para bash en particular, esto se documenta en la sección "Expansión de nombre de archivo" del manual de bash; ejecutar info bash
y buscar "Expansión de nombre de archivo", o ver aquí .
El hecho de que esto sea hecho por el shell, y no por comandos individuales, tiene algunas consecuencias interesantes (y a veces sorprendentes). Lo mejor de todo es que el manejo de comodines es consistente para (casi) todos los comandos; Si el shell no hiciera esto, inevitablemente algunos comandos no molestarían, y otros lo harían de maneras sutilmente diferentes que el autor pensó que eran "mejores". (Creo que el shell de comandos de Windows tiene este problema, pero no estoy lo suficientemente familiarizado como para comentar más).
Por otro lado, es difícil escribir un comando para cambiar el nombre de varios archivos. Si tú escribes:
mv *.log *.log.bak
probablemente fallará, ya que *.log.bak
se expande en función de los archivos que ya existen en el directorio actual. Hay comandos que hacen este tipo de cosas, pero tienen que usar su propia sintaxis para especificar cómo se van a renombrar los archivos. Algunos comandos (como find
) pueden hacer su propia expansión comodín; tienes que citar los argumentos para suprimir la expansión del shell:
find . -name '*.txt' -print
La expansión de comodines del shell se basa completamente en la sintaxis del argumento de la línea de comandos y el conjunto de archivos existentes. No puede verse afectado por el significado del comando. Por ejemplo, si desea mover todos los .log
archivos al directorio principal, puede escribir:
mv *.log ..
Si olvida el ..
:
mv *.log
y resulta que hay exactamente dos .log
archivos en el directorio actual, se expandirá a:
mv one.log two.log
que cambiará el nombre one.log
y el clobber two.log
.
EDITAR : Y después de 52 votos a favor, una aceptación y una insignia de Guru, tal vez debería responder la pregunta en el título.
La opción -d
u no le dice que solo enumere directorios. Le dice que enumere los directorios como ellos mismos, no sus contenidos. Si le da un nombre a un directorio como argumento para , de manera predeterminada, enumerará el contenido del directorio, ya que generalmente eso es lo que le interesa. La opción le dice que enumere solo el directorio en sí. Esto puede ser particularmente útil cuando se combina con comodines. Si escribe:--directory
ls
ls
-d
ls -l a*
ls
le dará una lista larga de cada archivo cuyo nombre comienza con a
, y de los contenidos de cada directorio cuyo nombre comienza con a
. Si solo desea una lista de los archivos y directorios, una línea para cada uno, puede usar:
ls -ld a*
que es equivalente a:
ls -l -d a*
Recuerde nuevamente que el ls
comando nunca ve al *
personaje.
En cuanto a dónde está documentado esto, man ls
le mostrará la documentación para el ls
comando en casi cualquier sistema similar a Unix. En la mayoría de los sistemas basados en Linux, el ls
comando es parte del paquete GNU coreutils; si tiene el info
comando, ya sea info ls
o info coreutils ls
debería darle una documentación más completa y definitiva. Otros sistemas, como MacOS, pueden usar diferentes versiones del ls
comando y pueden no tener el info
comando; para esos sistemas, use man ls
. Y ls --help
mostrará un mensaje de uso relativamente corto (117 líneas en mi sistema) si está utilizando la implementación GNU coreutils.
Y sí, incluso los expertos necesitan consultar la documentación de vez en cuando. Ver también esta broma clásica .