Que signifie! $?

32

Je suis à travers un tutoriel et il est mentionné pour exécuter cette commande:

sudo chmod 700 !$

Je ne suis pas familier avec !$. Qu'est-ce que ça veut dire?

Andrew
la source
5
Il est généralement prudent d'essayer echoquelque chose si vous n'êtes pas sûr de ce que ça va faire.
Shadur
8
@Shadur, pas toujours. echo $(rm -rf /)
cjm
1
@cjm Sauf si vous utilisez un système vraiment ancien, vous aurez besoin de cette --no-preserve-rootoption, et si vous voyez les mots "pas de réserve" dans un programme, réfléchissez bien à ce qu'il fait.
wchargin le
4
@WChargin Soyez très prudent en supposant que "vraiment vieux" et "pas Linux / ne pas utiliser GNU coreutils" sont la même chose; ils ne sont pas.
Chris Down

Réponses:

44

Fondamentalement, c'est le dernier argument de la commande précédente.

!$est la "fin" de la commande précédente. Prenons l'exemple suivant: Nous commençons par rechercher un mot dans un fichier:

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

si Joe est dans cette liste d'utilisateurs, nous voulons le supprimer. Nous pouvons soit lancer vi avec cette longue arborescence de répertoires en tant qu'argument, soit aussi simplement que vi !$Which bash se développe:

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

( source ; guide pratique, en passant)


La distinction entre ce !$jeton et la variable shell spéciale ne vaut rien $_. En effet, les deux développent le dernier argument de la commande précédente. Toutefois, !$est étendu lors de l’extension de l’historique , tandis que $_lors de l’ expansion des paramètres . Une conséquence importante de cela est que, lorsque vous utilisez !$la commande développée, elle est enregistrée dans votre historique.

Par exemple, considérons les frappes au clavier

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

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

(Les seuls caractères modifiés sont le $!et $_au milieu.)

Dans le premier cas, lorsque vous appuyez sur Up, la ligne de commande echo Foo Jarest lue Foo Jar. La dernière ligne écrite sur stdout est donc .

Dans ce dernier cas, lorsque vous appuyez sur Up, la ligne de commande lit echo $_ bar, mais a maintenant $_une valeur différente de celle utilisée précédemment. En fait, $_c'est maintenant Jar, donc la dernière ligne écrite dans stdout est Jar Jar.

Une autre conséquence est qu’il _peut être utilisé dans d’autres développements de paramètres, par exemple la séquence de commandes

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

impressions isomorphism isosceles. Mais il n'y a pas " ${!$%morphism}" d'expansion analogue .

Pour plus d'informations sur les phases d'expansion dans Bash, voir la EXPANSIONsection de man 1 bash(cela s'appelle Shell Expansions dans l'édition en ligne). La HISTORY EXPANSIONsection est séparée.

wchargin
la source
6
Agréable. Bon à savoir. Aussi, bonne chose, il y a Stack Exchange. Il est difficile de chercher sur Google quelque chose comme!$
Andrew
4
En passant, sur la ligne de commande, vous pouvez insérer le dernier argument de la commande précédente par insert-last-argument, généralement lié à M-..
Choroba
1
@ Andrew s'il vous plaît n'oubliez pas d'accepter cela si cela répond à votre question. Accepter et augmenter le vote plutôt que d’afficher des commentaires, c’est la façon dont les remerciements sont exprimés sur le réseau SE, voir ici pour la position "officielle".
terdon
1
@ Andrew FYI, j'ai cherché sur Google "bash bang dollar" et obtenu des résultats décents, y compris ce lien en tant que troisième liste.
wchargin
1
@terdon J'ai essayé d'accepter la réponse hier soir, mais c'était si rapide que j'ai été obligé d'attendre pour l'accepter.
Andrew
4

À proprement parler, !$c'est le dernier mot de la dernière commande de la liste de l'historique.

word - Une séquence de caractères traitée comme une unité par le shell. Les mots peuvent ne pas inclure de métacaractères non cités.

métacaractère - Caractère qui, lorsqu'il est non cité, sépare les mots. Un métacaractère est un blanc ou un des caractères suivants: '|', '&', ';', '(', ')', '<' ou '>'

blank - Un espace ou une tabulation.

Exemples:

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
la source
-3

!$ vous donnera la dernière commande utilisée pour cet utilisateur particulier ....

vous pouvez également trouver l'historique des commandes utilisées précédemment en utilisant historycommande ... essayez-le ....

REMARQUE: Pour un utilisateur particulier, toutes les commandes utilisées précédemment seront stockées dans le fichier d’historique bash.

Karthik G
la source
1
Les autres réponses sont bonnes. Celui-ci est faux.
Scott