¿Qué significa! $

32

Estoy siguiendo un tutorial y menciona ejecutar este comando:

sudo chmod 700 !$

No estoy familiarizado con !$. Qué significa eso?

Andrés
fuente
55
En general, es seguro intentar echoalgo si no está seguro de lo que hará.
Shadur
8
@Shadur, no siempre. echo $(rm -rf /)
cjm
1
@cjm A menos que esté en un sistema realmente antiguo, necesitará la --no-preserve-rootopción allí, y si ve las palabras "no preservar" en un programa, es mejor que piense detenidamente sobre lo que hace.
wchargin
44
@WChargin Tenga mucho cuidado asumiendo que "muy viejo" y "no Linux / no usando GNU coreutils" son lo mismo; no lo son
Chris Down el

Respuestas:

44

Básicamente, es el último argumento del comando anterior.

!$es el "fin" del comando anterior. Considere el siguiente ejemplo: Comenzamos buscando una palabra en un archivo:

grep -i joe /some/long/directory/structure/user-lists/list-15

Si Joe está en esa lista de usuarios, queremos eliminarlo. Podemos activar vi con ese árbol de directorios largo como argumento, o simplemente como vi !$Which bash se expande a:

vi /some/long/directory/structure/user-lists/list-15

( fuente ; guía práctica, por cierto)


No vale nada la distinción entre este !$token y la variable de shell especial $_. De hecho, ambos se expanden al último argumento del comando anterior. Sin embargo, !$se expande durante la expansión del historial , mientras que $_se expande durante la expansión de parámetros . Una consecuencia importante de esto es que, cuando usa !$, el comando expandido se guarda en su historial.

Por ejemplo, considere las pulsaciones de teclas

  • echo Foo Enter echo !$ Jar Enter Up Enter; y

  • echo Foo Enter echo $_ Jar Enter Up Enter.

(Los únicos caracteres cambiados son $!y $_en el medio).

En el primero, cuando presiona Up, se lee la línea de comando echo Foo Jar, por lo que la última línea escrita en stdout es Foo Jar.

En el último, cuando presiona Up, la línea de comando se lee echo $_ bar, pero ahora $_tiene un valor diferente al que tenía anteriormente; de ​​hecho, $_es ahora Jar, por lo que la última línea escrita en stdout es Jar Jar.

Otra consecuencia es que _puede usarse en otras expansiones de parámetros, por ejemplo, la secuencia de comandos

printf '%s '    isomorphism
printf '%s\n'   ${_%morphism}sceles

impresiones isomorphism isosceles. Pero no hay una " ${!$%morphism}" expansión análoga .

Para obtener más información sobre las fases de expansión en Bash, consulte la EXPANSIONsección deman 1 bash (esto se llama Expansiones de Shell en la edición en línea). La HISTORY EXPANSIONsección está separada.

wchargin
fuente
66
Agradable. Bueno saber. Además, algo bueno es Stack Exchange. Es difícil buscar en Google algo así!$
Andrew
44
Por cierto, en la línea de comando, puede insertar el último argumento del comando anterior insert-last-argument, generalmente vinculado a M-..
choroba
1
@ Andrew, recuerda aceptar esto si responde a tu pregunta. Aceptar y votar en lugar de publicar comentarios es cómo se expresan las gracias en la red SE, vea aquí la postura "oficial".
terdon
1
@ Andrew FYI, busqué en Google "bash bang dollar" y obtuve resultados decentes, incluido este enlace como el tercer listado.
wchargin
1
@terdon Intenté aceptar la respuesta anoche, pero fue tan rápido que me vi obligado a esperar para aceptarla.
Andrew
4

Estrictamente hablando !$es la última palabra del último comando de la lista del historial.

palabra: una secuencia de caracteres que el shell trata como una unidad. Las palabras pueden no incluir metacaracteres sin comillas.

metacarácter: un carácter que, cuando no se cita, separa las palabras. Un metacarácter es un espacio en blanco o uno de los siguientes caracteres: '|', '&', ';', '(', ')', '<' o '>'

en blanco: un espacio o un carácter de tabulación.

Ejemplos:

set -o history # enable command history
set -o histexpand # enable ! style history substitution

HISTSIZE=10

# save all lines on the history list    
HISTCONTROL=
HISTIGNORE=

date
echo !$ # prints date

date>/dev/null
echo !$ # prints /dev/null

echo a b c>/dev/null
echo !$ # prints /dev/null

HISTCONTROL=ignorespace # lines which begin with a space character are not saved in the history list
echo a b c
 echo d e f # space at the beginning
echo !$ # prints c
Evgeny Vereshchagin
fuente
-3

!$ le dará el último comando utilizado para ese usuario en particular ...

también puede encontrar el historial de comandos utilizados anteriormente mediante el historycomando ... pruébelo ...

NOTA: Para un usuario en particular, todos los comandos utilizados anteriormente se almacenarán en el archivo de historial bash.

karthik G
fuente
1
Las otras respuestas son correctas. Este está mal.
Scott