¿Es posible imprimir la expansión de shell?

18

Sé que hay un conjunto específico de reglas que expanden los comandos que el usuario escribió. (hablemos de bash shell)

¿Es posible imprimir un comando en el formulario después de la expansión de shell? Parece ser una buena utilidad para aprender y asegurarse de cómo shell expande caracteres especiales.

p.ej

$ echo *

{all the filenames in current dir}

Quiero imprimir el comando expandido, que es la siguiente línea:

echo {all the filenames in .}
Weishi Zeng
fuente

Respuestas:

13

Solo usa echo... ponlo delante del comando que deseas expandir. Lo uso con bastante frecuencia.

$ ls
one.txt
two.txt
three.dat
$ echo rm *.txt
rm one.txt two.txt
$ rm *.txt

Puede usar Homey Delpara agregar / eliminar rápidamente lo anterior echo.

EDITAR
Como se señaló en los comentarios, esto no funcionará si el comando no es sólo un simple comando (como si es un forbucle, utiliza el tubo |, o &&, o cualquier otra cosa por el estilo).

BenjiWiebe
fuente
1
Esto es lo que hago al probar un script
Barmar, el
Esto aún se ve afectado por otros tokens de shell echo cat * | someprogramque no hacen lo que podría pensar de esta respuesta.
Kroltan
13

Puedes usar set -x.

Por ejemplo, considere el script:

$ cat script.sh
set -x
echo *

Cuando se ejecuta, muestra la echodeclaración expandida antes de ejecutarla realmente:

$ bash script.sh
+ echo file1 file2 file3 script.sh
file1 file2 file3 script.sh

Y, como señala Kundor, esto también funciona interactivamente en la línea de comando:

$ set -x
+ set -x
$ echo *
+ echo file1 file2 file3 script.sh
file1 file2 file3 script.sh

Documentación

man bashexplica lo que set -xhace lo siguiente:

Después de expandir cada comando simple, para comando, comando de caso, comando de selección o aritmética para comando, muestre el valor expandido de PS4, seguido del comando y sus argumentos expandidos o la lista de palabras asociadas.

El valor predeterminado para PS4es, como se muestra arriba, un signo más seguido de un espacio.

John1024
fuente
2
Y también funciona bien en un shell interactivo (que creo que el OP está buscando)
Nick Matteo
7

Para un shell interactivo, presionar Ctrl+xseguido de *después de escribir el patrón glob editará su línea de comando con ese patrón glob expandido. Desde la página de manual de bash:

glob-expand-word ( C-x *)

La palabra anterior al punto se trata como un patrón para la expansión del nombre de ruta y se inserta la lista de nombres de archivo coincidentes, reemplazando la palabra. Si se proporciona un argumento numérico, se agrega un asterisco antes de la expansión del nombre de ruta.

También te puede interesar glob-list-expansions ( Ctrl+x, g).

jamesdlin
fuente
Estoy usando bash de Mac OS. Intenté ctrl + x, comando + x. No estoy seguro si hace alguna edición de línea de comando. podrías elaborar más?
Weishi Zeng
@WeishiZeng No sé por qué no te funciona. ¿Presionó Ctrl+x, *inmediatamente después de escribir echo *y antes de presionar la tecla Intro? Si aún no funciona, puede modificar ~/.inputrcy vincular glob-expand-word a otra cosa.
jamesdlin
contrl + x mueve el cursor a la palabra echo, pero no edita nada. "Ctrl + x " , ¿qué significa? (¿es ctrl + x O ctrl + ??) * está en Shift, así que necesito presionar Shift también para obtener un *, ¿verdad?
Weishi Zeng
Derecha, presione Ctrl+xseguido de Shift+8. Puede intentar ver si Ctrl+x, gfunciona o, como dije antes, asignar su propia clave en el .inputrcarchivo.
jamesdlin
1

Si desea ver cómo se expanden o se tokenizan los argumentos, puede usar un programa o script que imprima sus argumentos. Aquí hay una implementación en bash:

#!/bin/bash

for (( i = 0; i <= $#; ++i )); do
    printf 'argv[%d] = %s\n' $i "${!i}"
done

Suponiendo que pones eso en un archivo llamado printargs.sh(y lo hiciste ejecutable), obtendrías un resultado como este

$ ./printargs.sh a{1..3}b
argv[0] = ./printargs.sh
argv[1] = a1b
argv[2] = a2b
argv[3] = a3b
jjlin
fuente