Traté de crear un script echo
introduciendo el contenido en un archivo, en lugar de abrirlo con un editor
echo -e "#!/bin/bash \n /usr/bin/command args" > .scripts/command
La salida :
bash:! / bin / bash: evento no encontrado
He aislado este extraño comportamiento a la explosión .
$ echo !
!
$ echo "!"
bash: !: event not found
$ echo \#!
#!
$ echo \#!/bin/bash
bash: !/bin/bash: event not found
- ¿Por qué la explosión está causando esto?
- ¿Cuáles son estos "eventos" a los que se refiere bash?
- ¿Cómo puedo superar este problema e imprimir "#! / Bin / bash" en la pantalla o en mi archivo?
command-line
bash
echo
Stefan
fuente
fuente
$''
. Por ejemplo,echo $'1!\n2!\n3!\n'
imprime cada número seguido de una explosión y una nueva línea.echo '0123'"$var"'456'
observe dos pares de comillas simples y un par de comillas dobles.Como Richm dijo , bash está tratando de hacer un partido de historia . Otra forma de evitarlo es escapar de la explosión con un
\
:Aunque tenga cuidado con las comillas dobles,
\
no se elimina:fuente
"\!"
realidad se expande\!
, no!
, supuestamente para el cumplimiento de POSIX.!
entre comillas dobles sin comportamiento mágico? Esto es una locura ...!
inicia una sustitución del historial (un "evento" es una línea en el historial del comando); por ejemplo se!ls
expande a la última línea de comando que contienels
, y se!?foo
expande a la última línea de comando que contienefoo
. También puede extraer palabras específicas (por ejemplo, se!!:1
refiere a la primera palabra del comando anterior) y más; Vea el manual para más detalles.Esta característica se inventó para recuperar rápidamente los comandos anteriores en los días en que la edición de la línea de comandos era primitiva. Con los shells modernos (al menos bash y zsh) y copiar y pegar, la expansión del historial ya no es tan útil como solía serlo, sigue siendo útil, pero puede sobrevivir sin ella.
Puede cambiar qué carácter desencadena la sustitución del historial configurando la
histchars
variable; si rara vez usa la sustitución del historial, puede configurar, por ejemplo,histchars='¡^'
para que active la¡
expansión del historial en lugar de!
. Incluso puede desactivar la función por completo conset +o histexpand
.fuente
Para poder deshabilitar la expansión del historial en una línea de comando en particular, puede usar
space
como el tercer carácter de$histchars
:Luego, si ingresa su comando con un espacio inicial, no se realizará la expansión del historial.
Sin embargo, tenga en cuenta que los espacios iniciales también se usan cuando
$HISTCONTROL
contieneignorespace
como una forma de decirle quebash
no registre una línea de comando en el historial.Si desea ambas funciones de forma independiente, deberá elegir otro personaje como el tercer personaje de
$histchars
. Desea uno que no afecte la forma en que se interpreta su comando. Algunas opciones:\
):\echo foo
funciona pero tiene el efecto secundario de deshabilitar los alias o las palabras clave.si no le importa escribir dos teclas, se puede elegir cualquier personaje que normalmente no aparece en primera posición (
%
,@
,?
, escoger su propio) y crea un alias de vacío para ello:Luego ingrese ese carácter, espacio y su comando:
(no podrá registrar un comando donde la sustitución del historial ha sido desactivada. Tenga en cuenta también que el tercer carácter predeterminado de
$histchars
es#
para que la expansión del historial no se realice en los comentarios. Si lo cambia e ingresa comentarios en el pronto, debe tener en cuenta el hecho de que las secuencias! pueden expandirse allí).fuente
Las soluciones propuestas no funcionan, por ejemplo, en el siguiente ejemplo:
En este caso, la explosión se puede imprimir usando su código octal ASCII:
fuente
!
está entre comillas dobles, donde, como indican otras respuestas, conserva su significado de expansión de historial. Podrías usarbash -c 'echo '\''hello World!'\'
obash -c "echo 'hello World"\!"'"
.Desde Bash 4.3, ahora puede usar comillas dobles para citar el carácter de expansión del historial:
fuente
!
seguido por"
eso ya no es especial.echo "foo!"
está bien,echo "foo!bar"
no lo está