- 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
man
yinfo
dó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áls
haciendo esto sino la fiesta.Respuestas:
La sintaxis
a*
y la*a*
implementa el shell, no ells
comando.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 a3
y pasarlos como argumentos als
. Ells
comando en sí mismo nunca ve al*
personaje; sólo ve las tres argumentosa1
,a2
ya3
.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 ya3
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:
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 (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
.log
archivos al directorio principal, puede escribir:Si olvida el
..
:y resulta que hay exactamente dos
.log
archivos en el directorio actual, se expandirá a:que cambiará el nombre
one.log
y 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
-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
le 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
ls
comando nunca ve al*
personaje.En cuanto a dónde está documentado esto,
man ls
le mostrará la documentación para ells
comando en casi cualquier sistema similar a Unix. En la mayoría de los sistemas basados en Linux, ells
comando es parte del paquete GNU coreutils; si tiene elinfo
comando, ya seainfo ls
oinfo coreutils ls
debería darle una documentación más completa y definitiva. Otros sistemas, como MacOS, pueden usar diferentes versiones dells
comando y pueden no tener elinfo
comando; para esos sistemas, useman ls
. Yls --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 .
fuente
a*
expande a una lista de todos los archivos en el directorio actual cuyos nombres comienzan cona
.ls subdir/a*
echo
se. 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 failglob
provoca el mismo comportamiento. Establecernullglob
pero nofailglob
hace 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--directory
opció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
-F
opció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 llamaglob
bing 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 glob
en el shell de una distribución clásica de Linux (o vea esto ) para obtener más información sobreglob
bing.A principios de Unix, en
glob
realidad 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 -d
enumera archivos y directorios ...La
ls
pá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
ls
enumera el contenido de los directorios cuando se les da su nombre, y hará lo mismo para los enlaces simbólicos a los directorios. La-d
opción significa, "cuando se dan los nombres de los directorios" (que también se pueden dar implícitamente porglob
bing) , 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
-d
opció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 elfind
comando.En resumen: de forma predeterminada,
ls
muestra el contenido de los directorios cuando se les asigna su nombre de ruta.-d
cambia 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
ls
recibe 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
ls
comando 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