Para Unix, las respuestas a continuación son correctas. (En Windows, se realiza mediante programas individuales, aunque generalmente de forma automática mediante la biblioteca de tiempo de ejecución antes de main ())
User1686
Respuestas:
24
bash (o lo que sea que use como shell), es lo primero que lee cualquier entrada, y comenzará a interpretar caracteres especiales como ?y *. *se expande a cualquier coincidencia en la CWD , lo que significa que el asterisco se sustituye por dichas coincidencias.
En la mayoría de los casos, esto es bastante sencillo, pero puede llevar a algunos casos confusos de vez en cuando.
Considera lo siguiente. Un directorio tiene este contenido:
prueba (archivo regular)
prueba1 (directorio)
test2 (directorio)
test3 (directorio)
Si luego escribe mv *algo que sucede aparentemente extraño: test3está ahí, pero el resto se ha ido. Si bien es extraño al principio, tiene sentido una vez que entiendes a qué le pasa realmente bash mv. Debido al asterisco, bash interpreta mv *como mv test test1 test2 test3, y cuando mv obtiene esa lista, asumirá que el último argumento es el destino, que es donde se habrían movido todos los archivos.
En cuanto a los comandos que enumeró:
echo *puede funcionar como un pobre hombre ls. El shell expandirá el asterisco a lo que esté en ese directorio y, como estoy seguro de que ya lo sabe, echoliteralmente hará eco de todo lo que le haya pasado como argumento.
cp temp temp*se comportará de manera similar al mvcomando que describí anteriormente, a menos que solo haya un directorio llamado temp, en cuyo caso el nombre de origen y destino es el mismo, es decir, no hará nada.
No hay nada "pobre" sobre el uso en *lugar de ls. Por ejemplo, for f in *; does más confiable que for f in $(ls)si un nombre de archivo contiene espacios en blanco o un carácter global. (Sin embargo, fallará si no hay archivos en el CWD, por lo que debe verificar ese caso.)
rici
1
@rici Para eso shopt nullglobestá.
un CVn
3
En cuanto a echo *, ese truco puede salvarte en algunos casos.
un CVn
2
Entrando con: archivos antepuestos con "-" en carpetas arbitrarias que activan interruptores indeseables. Eliminarlos no es muy divertido hasta que te das cuenta de que rm ./-stupidfile funciona.
ɯͽbρɯͽ
1
@ ǝɲǝɲbρɯͽ Me di cuenta cuando una vez necesité eliminar el contenido de un directorio que contenía archivos con el nombre de archivo que representa posiciones en un sistema de coordenadas, de -1024x-1024 a 1024x1024. Fue entonces cuando supe por primera vez sobre escapar.
Jarmund
5
Como ya se dijo, el shell se expande, *así que echoreciba como argumentos lo que sea que encuentre en el directorio actual. Sin embargo, tenga en cuenta que si la expansión no conduce a nada, es decir, en ese caso si el directorio no contiene archivos no ocultos, *se deja sin cambios y se pasa como está al comando llamado (a menos que se usen opciones no estándar con algunos shells como bash). echo *entonces no se va a comportar como un hombre pobre, lsya que el primero no imprimirá nada mientras que el segundo imprimirá *.
Del mismo modo, cp /tmp/temp temp*creará un archivo con nombre temp*en el directorio actual si aún no hay al menos un archivo cuyo nombre comience temp.
Finalmente, si desea *que se pase sin cambios en cualquier caso, puede protegerlo de la expansión utilizando comillas simples '*', comillas dobles "*"o barra diagonal inversa \*.
En Bash, el shell se ocupa de ello. Ves que si incluso lo intentas *sin eco
Nota: basado en algunos comentarios, sugeriría al ejecutar * ENTER, crear un directorio y usar el comando táctil para crear algunos archivos, y asegurarse de que ninguno de ellos, o al menos asegurarse de que el primero alfabéticamente, no sea el nombre de cualquier script o comando en la ruta.
$ *
bash: a: command not found
$ echo *
a a.aa a.ab a.b a.htm a.tx
Entonces ls *es un poco cliché
En Windows, *se maneja con el comando, por dir *.*lo que no es un cliché.
Nota: al ver algunos comentarios, agregaría, existe el riesgo de ejecutar * y luego ENTER. Si tiene un archivo llamado rm que está primero en la lista del directorio, entonces es peligroso porque cualquier cosa después se eliminaría. Además, y esto es menos improbable, si el primer archivo en la lista del directorio es el nombre de un script en la ruta, entonces lo ejecutará.
Tenga en cuenta que podría haber un archivo llamado rm, por supuesto.
Volker Siegel
1
... y otro llamado -rf
ɯͽbρɯͽ
1
@ ǝɲǝɲbρɯͽ ¿puede tener un archivo cuyo nombre de archivo es -rf? Lo intenté touch -rfy touch \-rfno lo está creando.
barlop
@barlop comenté arriba; la interfaz gráfica de usuario (como gedit) los maneja bien, pero dado que el shell (al menos bash) pasa esto, requiere ./ en el frente. Si alguna vez crea accidentalmente un archivo de este tipo, rm intenta insinuarlo, pero si no lo hace: espero que esto solo termine en una carpeta temporal con elementos descartables.
ɯͽbρɯͽ
@ ǝɲǝɲbρɯͽ No entiendo lo que quieres decir en absoluto, te pregunto cómo puedes crear un archivo con el nombre -rf. (Entiendo el peligro de un archivo llamado rm y un archivo llamado -rf, y el problema de escribir * y presionar enter en una carpeta importante, no planeo hacer eso)
barlop
-1
El shell realiza varias expansiones antes de entregar los argumentos al comando.
Técnicamente, lo que está escribiendo es correcto, pero sin los enlaces, esta respuesta realmente no hace nada para responder la pregunta. Considere incorporar los detalles relevantes.
un CVn
@ MichaelKjörling Estoy de acuerdo con lo de los enlaces, pero el OP simplemente preguntó si el shell o el comando en sí manejaban los argumentos. La respuesta de Glenn simplemente indica que el shell los maneja, por lo que es una respuesta aceptable a la pregunta.
slhck
@slhck Por eso no marqué como NAA: queda algo que resuelve la pregunta después de quitar los enlaces. Eso no significa que esta sea una buena respuesta en mi opinión . (Ahora veo que mi comentario inicial podría ser interpretado de otra manera; por eso, lo siento, pero sigo pensando que tiene un valor suficiente para dejarlo donde está.)
un CVn
@ MichaelKjörling De acuerdo. Acabo de dejar el comentario para aquellos que lo marcaron (y lo marcarán) como NAA.
Respuestas:
bash (o lo que sea que use como shell), es lo primero que lee cualquier entrada, y comenzará a interpretar caracteres especiales como
?
y*
.*
se expande a cualquier coincidencia en la CWD , lo que significa que el asterisco se sustituye por dichas coincidencias.En la mayoría de los casos, esto es bastante sencillo, pero puede llevar a algunos casos confusos de vez en cuando.
Considera lo siguiente. Un directorio tiene este contenido:
Si luego escribe
mv *
algo que sucede aparentemente extraño:test3
está ahí, pero el resto se ha ido. Si bien es extraño al principio, tiene sentido una vez que entiendes a qué le pasa realmente bashmv
. Debido al asterisco, bash interpretamv *
comomv test test1 test2 test3
, y cuando mv obtiene esa lista, asumirá que el último argumento es el destino, que es donde se habrían movido todos los archivos.En cuanto a los comandos que enumeró:
echo *
puede funcionar como un pobre hombrels
. El shell expandirá el asterisco a lo que esté en ese directorio y, como estoy seguro de que ya lo sabe,echo
literalmente hará eco de todo lo que le haya pasado como argumento.cp temp temp*
se comportará de manera similar almv
comando que describí anteriormente, a menos que solo haya un directorio llamado temp, en cuyo caso el nombre de origen y destino es el mismo, es decir, no hará nada.fuente
*
lugar dels
. Por ejemplo,for f in *; do
es más confiable quefor f in $(ls)
si un nombre de archivo contiene espacios en blanco o un carácter global. (Sin embargo, fallará si no hay archivos en el CWD, por lo que debe verificar ese caso.)shopt nullglob
está.echo *
, ese truco puede salvarte en algunos casos.Como ya se dijo, el shell se expande,
*
así queecho
reciba como argumentos lo que sea que encuentre en el directorio actual. Sin embargo, tenga en cuenta que si la expansión no conduce a nada, es decir, en ese caso si el directorio no contiene archivos no ocultos,*
se deja sin cambios y se pasa como está al comando llamado (a menos que se usen opciones no estándar con algunos shells comobash
).echo *
entonces no se va a comportar como un hombre pobre,ls
ya que el primero no imprimirá nada mientras que el segundo imprimirá*
.Del mismo modo,
cp /tmp/temp temp*
creará un archivo con nombretemp*
en el directorio actual si aún no hay al menos un archivo cuyo nombre comiencetemp
.Finalmente, si desea
*
que se pase sin cambios en cualquier caso, puede protegerlo de la expansión utilizando comillas simples'*'
, comillas dobles"*"
o barra diagonal inversa\*
.fuente
En Bash, el shell se ocupa de ello. Ves que si incluso lo intentas
*
sin ecoNota: basado en algunos comentarios, sugeriría al ejecutar * ENTER, crear un directorio y usar el comando táctil para crear algunos archivos, y asegurarse de que ninguno de ellos, o al menos asegurarse de que el primero alfabéticamente, no sea el nombre de cualquier script o comando en la ruta.
Entonces
ls *
es un poco clichéEn Windows,
*
se maneja con el comando, pordir *.*
lo que no es un cliché.Nota: al ver algunos comentarios, agregaría, existe el riesgo de ejecutar * y luego ENTER. Si tiene un archivo llamado rm que está primero en la lista del directorio, entonces es peligroso porque cualquier cosa después se eliminaría. Además, y esto es menos improbable, si el primer archivo en la lista del directorio es el nombre de un script en la ruta, entonces lo ejecutará.
fuente
rm
, por supuesto.-rf
? Lo intentétouch -rf
ytouch \-rf
no lo está creando.-rf
. (Entiendo el peligro de un archivo llamado rm y un archivo llamado -rf, y el problema de escribir * y presionar enter en una carpeta importante, no planeo hacer eso)El shell realiza varias expansiones antes de entregar los argumentos al comando.
Consulte también https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion
No es específico de bash, consulte http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_01
fuente