- al especificar
ls --directory a*que solo debe enumerar los directorios que comienzan cona* - PERO enumera archivos y directorios que comienzan con
a
Preguntas :
- ¿Dónde puedo encontrar documentación sobre esto, aparte de
manyinfodónde creo que busqué a fondo? - funciona esto solo en BASH?

echo a*también le mostrará una lista de los archivos que comienzan cona(si corresponde). Solo para dejar más claro que no estálshaciendo esto sino la fiesta.Respuestas:
La sintaxis
a*y la*a*implementa el shell, no ellscomando.Cuando escribes
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 cona. Por ejemplo, podría expandirsea*a la secuenciaa1 a2 a3y pasarlos como argumentos als. Ellscomando en sí mismo nunca ve al*personaje; sólo ve las tres argumentosa1,a2ya3.Para propósitos de expansión de comodines, "archivos" se refiere a todas las entidades en el directorio actual. Por ejemplo,
a1podría ser un archivo normal,a2podría ser un directorio ya3podrí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 bashy 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:
probablemente fallará, ya que
*.log.bakse 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 (comofind) pueden hacer su propia expansión comodín; tienes que citar los argumentos para suprimir la expansión del shell: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
.logarchivos al directorio principal, puede escribir:Si olvida el
..:y resulta que hay exactamente dos
.logarchivos en el directorio actual, se expandirá a:que cambiará el nombre
one.logy el clobbertwo.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
-du 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:--directorylsls-dlsle dará una lista larga de cada archivo cuyo nombre comienza cona, y de los contenidos de cada directorio cuyo nombre comienza cona. Si solo desea una lista de los archivos y directorios, una línea para cada uno, puede usar:que es equivalente a:
Recuerde nuevamente que el
lscomando nunca ve al*personaje.En cuanto a dónde está documentado esto,
man lsle mostrará la documentación para ellscomando en casi cualquier sistema similar a Unix. En la mayoría de los sistemas basados en Linux, ellscomando es parte del paquete GNU coreutils; si tiene elinfocomando, ya seainfo lsoinfo coreutils lsdebería darle una documentación más completa y definitiva. Otros sistemas, como MacOS, pueden usar diferentes versiones dellscomando y pueden no tener elinfocomando; para esos sistemas, useman ls. Yls --helpmostrará 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 .
fuente
a*expande a una lista de todos los archivos en el directorio actual cuyos nombres comienzan cona.ls subdir/a*echose. Entonces, si quieres saber qué sucede cuando lo hacesls a*, primero ejecutaecho ls a*echo a*... el caparazón se expande globalmente de todos modosshopt -s failglobprovoca el mismo comportamiento. Establecernullglobpero nofailglobhace que, por ejemplo, se*nosuchfile*expanda a una cadena vacía.Ver la respuesta de Keith Thompson; pero para explicar por qué
ls --directory a*muestra archivos y directorios: la--directoryopción no suprime los archivos que no son de directorio. En cambio, enumera los directorios como tales, mientras que de lo contrario enumeraría su contenido. Ejemplo:fuente
-FopciónPara ser muy explícito, está documentado en la página del manual ls (1) :
-d, --directorio de entradas de directorio de lista en lugar de contenidos, y no desreferencia los enlaces simbólicos
para ser justos, "las entradas en lugar de los contenidos" probablemente podrían ser más explicativas:
fuente
Globbing
Como se ha explicado, la expansión de
*(y expansiones similares) se llamaglobbing en la jerga de Unix, y generalmente es una característica del procesador de comandos (conocido como "shell" en lenguaje Unix). Por lo tanto, el engorde puede usarse en muchos otros lugares también; escribaman 7 globen el shell de una distribución clásica de Linux (o vea esto ) para obtener más información sobreglobbing.A principios de Unix, en
globrealidad fue implementado por un programa separado llamado/etc/glob(consulte la página 10 de este antiguo manual de UNIX para obtener documentación al respecto). Hoy en día, es una rutina de código suministrada por bibliotecas de códigos, y es comúnmente utilizada por shells. Fuente : Wikipedia .Directorios
En cuanto a por qué
ls -denumera archivos y directorios ...La
lspágina del manual explica por qué sucede esto, pero con una explicación muy concisa. Así que aquí hay un intento de una explicación ampliada:Por defecto
lsenumera el contenido de los directorios cuando se les da su nombre, y hará lo mismo para los enlaces simbólicos a los directorios. La-dopción significa, "cuando se dan los nombres de los directorios" (que también se pueden dar implícitamente porglobbing) , solo muestra los _name_s de los directorios, pero no su contenido. De manera similar, cuando se le proporcione (explícita o implícitamente ) nombre (s) de enlaces simbólicos a directorios , muestre el nombre del archivo del enlace simbólico, no el contenido del directorio al que hace referencia.La
-dopción no tiene nada que ver, por lo que puedo decir, con qué elementos están listados; esto se puede hacer (fuente: aquí ) confind, así:find . -maxdepth 1 -type d. No estoy seguro de si hay una buena manera de hacerlo solo con GNUls. Aquí hay algunos ejemplos de cómo usar elfindcomando.En resumen: de forma predeterminada,
lsmuestra el contenido de los directorios cuando se les asigna su nombre de ruta.-dcambia este comportamiento, mostrando solo el nombre del directorio en sí, como se haría para un archivo estándar.fuente
Documentación no dice que las listas únicas entradas de directorio Bur más bien cuando
lsrecibe el nombre de directorio que enumera la entrada del directorio en lugar de su contenido. La mejor manera de entender es con el ejemplo:fuente
La documentación es parte del shell . En particular, el shell realiza varias expansiones y sustituciones en un orden particular antes de ejecutar un comando.
La secuencia de expansiones de palabras para un shell compatible con Bourne es
Entonces, el
lscomando ni siquiera ve los*caracteres, los argumentos ya están expandidos con todos los archivos que coinciden con ela*patrón global. Esto es diferente a lo que ocurre en Windows, donde cada comando que necesita el nombre de archivo tiene que implementar esta característica.fuente
La palabra clave que necesita (
man bash) es "Expansión del nombre de ruta".fuente