Cosa significa! $?


32

Sto seguendo un tutorial che menziona l'esecuzione di questo comando:

sudo chmod 700 !$

Non ho familiarità con !$. Cosa significa?


5
In genere è sicuro provare a echoqualcosa se non si è sicuri di cosa farà.
Shadur,

8
@Shadur, non sempre. echo $(rm -rf /)
cjm

1
@cjm A meno che tu non sia su un sistema molto vecchio, avrai bisogno --no-preserve-rootdell'opzione lì dentro, e se vedi le parole "no preservare" in un programma, è meglio che pensi attentamente a ciò che fa.
wchargin,

4
@WChargin Stai molto attento supponendo che "veramente vecchio" e "non Linux / non usi i coreutils GNU" siano la stessa cosa; non lo sono.
Chris Down,

Risposte:


44

Fondamentalmente, è l'ultimo argomento del comando precedente.

!$è la "fine" del comando precedente. Considera il seguente esempio: iniziamo cercando una parola in un file:

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

se joe è in quell'elenco utenti, vogliamo rimuoverlo da esso. Possiamo accendere vi con quel lungo albero di directory come argomento, o semplicemente come vi !$Quale bash si espande in:

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

( fonte ; guida pratica, a proposito)


Non vale nulla la distinzione tra questo !$token e la speciale variabile shell $_. In effetti, entrambi si espandono all'ultimo argomento del comando precedente. Tuttavia, !$viene espanso durante l' espansione della cronologia , mentre $_viene espanso durante l' espansione dei parametri . Una conseguenza importante di ciò è che, quando si utilizza !$, il comando espanso viene salvato nella cronologia.

Ad esempio, considerare le sequenze di tasti

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

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

(Gli unici caratteri modificati sono $!e $_nel mezzo.)

Nel primo, quando si preme Up, viene visualizzata la riga di comando echo Foo Jar, quindi l'ultima riga scritta su stdout è Foo Jar.

In quest'ultimo caso, quando si preme Up, la riga di comando legge echo $_ bar, ma ora $_ha un valore diverso rispetto a prima: in effetti lo $_è ora Jar, quindi l'ultima riga scritta su stdout è Jar Jar.

Un'altra conseguenza è che _può essere utilizzato in altre espansioni di parametri, ad esempio la sequenza di comandi

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

stampe isomorphism isosceles. Ma non esiste un'analoga " ${!$%morphism}" espansione.

Per ulteriori informazioni sulle fasi di espansione in Bash, consultare la EXPANSIONsezione di man 1 bash(questo si chiama Shell Expansions nell'edizione online). La HISTORY EXPANSIONsezione è separata


6
Bello. Buono a sapersi. Inoltre, buona cosa c'è Stack Exchange. È difficile cercare su Google qualcosa del genere!$
Andrew

4
A proposito, sulla riga di comando, è possibile inserire l'ultimo argomento del comando precedente insert-last-argument, di solito associato a M-..
Choroba,

1
@Andrew, ricordati di accettare questo se risponde alla tua domanda. Accettare e migliorare piuttosto che pubblicare commenti è il modo in cui i ringraziamenti sono espressi sulla rete SE, vedi qui per la posizione "ufficiale".
terdon

1
@Andrew FYI, ho cercato su Google "bash bang dollar" e ho ottenuto risultati decenti, incluso questo link come terzo elenco.
mercoledì

1
@terdon Ho provato ad accettare la risposta ieri sera, ma è stato così veloce che sono stato costretto ad aspettare per accettarla.
Andrew,

4

A rigor di termini !$è l'ultima parola dell'ultimo comando dall'elenco cronologico.

parola - Una sequenza di caratteri trattati come una shell dalla shell. Le parole non possono includere metacaratteri non quotati.

metacarattere - Un personaggio che, quando non quotato, separa le parole. Un metacarattere è uno spazio vuoto o uno dei seguenti caratteri: '|', '&', ';', '(', ')', '<' o '>'

vuoto: uno spazio o un carattere di tabulazione.

Esempi:

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


-3

!$ ti darà l'ultimo comando usato per quel particolare utente ....

puoi anche trovare la cronologia dei comandi usati in precedenza usando il historycomando ... provalo ....

NOTA: per un determinato utente, tutti i comandi utilizzati in precedenza verranno archiviati nel file cronologico di bash.


1
Le altre risposte sono giuste. Questo è sbagliato.
Scott,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.