O que significa! $?

32

Estou seguindo um tutorial e ele menciona para executar este comando:

sudo chmod 700 !$

Eu não estou familiarizado !$. O que isso significa?

Andrew
fonte
5
Geralmente é seguro tentar echoalgo se você não tiver certeza do que ele fará.
precisa saber é o seguinte
8
@Shadur, nem sempre. echo $(rm -rf /)
Cjm 30/08/2013
1
@cjm A menos que você esteja em um sistema muito antigo, precisará da --no-preserve-rootopção existente e, se vir as palavras "sem preservação" em um programa, é melhor pensar com cuidado sobre o que faz.
wchargin
4
@WChargin Tenha muito cuidado assumindo que "realmente antigo" e "não Linux / não usando GNU coreutils" são a mesma coisa; eles não são.
Chris Baixo

Respostas:

44

Basicamente, é o último argumento para o comando anterior.

!$é o "fim" do comando anterior. Considere o seguinte exemplo: Começamos procurando uma palavra em um arquivo:

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

se joe estiver nessa lista de usuários, queremos removê-lo. Podemos iniciar o vi com essa longa árvore de diretórios como argumento, ou simplesmente como vi !$Qual bash se expande para:

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

( fonte ; guia prático, a propósito)


Não vale nada a distinção entre esse !$token e a variável shell especial $_. De fato, ambos se expandem para o último argumento do comando anterior. No entanto, !$é expandido durante a expansão do histórico , enquanto $_é expandido durante a expansão de parâmetros . Uma conseqüência importante disso é que, quando você usa !$, o comando expandido é salvo no seu histórico.

Por exemplo, considere as teclas digitadas

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

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

(Os únicos caracteres alteradas são o $!e $_no meio).

No primeiro, quando você pressiona Up, a linha de comando lê echo Foo Jar; portanto, a última linha gravada em stdout é Foo Jar.

Neste último, quando você pressiona Up, a linha de comando lê echo $_ bar, mas agora $_tem um valor diferente do que anteriormente - na verdade, $_é agora Jar, então a última linha gravada em stdout é Jar Jar.

Outra conseqüência é que _pode ser usado em outras expansões de parâmetros, por exemplo, a sequência de comandos

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

impressões isomorphism isosceles. Mas não há ${!$%morphism}expansão " " análoga .

Para obter mais informações sobre as fases de expansão no Bash, consulte a EXPANSIONseção man 1 bash(isso é chamado de expansões de shell na edição online). A HISTORY EXPANSIONseção é separada.

wchargin
fonte
6
Agradável. Bom saber. Além disso, é bom que haja Stack Exchange. É difícil pesquisar no Google algo parecido com!$
Andrew Andrew
4
BTW, na linha de comando, você pode inserir o último argumento do comando anterior insert-last-argument, normalmente vinculado a M-..
choroba
1
@ Andrew, lembre-se de aceitar isso se responder à sua pergunta. Aceitar e votar em vez de postar comentários é como os agradecimentos são expressos na rede SE, veja aqui a posição "oficial".
terdon
1
@ Andrew FYI, pesquisei no Google por "bash bang dollar" e obtive resultados decentes, incluindo este link como a terceira listagem.
precisa saber é o seguinte
1
@terdon Tentei aceitar a resposta ontem à noite, mas foi tão rápido que fui obrigado a esperar para aceitá-la.
Andrew
4

Estritamente falando, !$é a última palavra do último comando da lista de histórico.

word - Uma sequência de caracteres tratados como uma unidade pelo shell. As palavras podem não incluir metacaracteres não citados.

metacaractere - Um caractere que, quando não está entre aspas, separa as palavras. Um metacaractere é um espaço em branco ou um dos seguintes caracteres: '|', '&', ';', '(', ')', '<' ou '>'

blank - Um caractere de espaço ou tabulação.

Exemplos:

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
fonte
-3

!$ lhe dará o último comando usado para esse usuário em particular ....

você também pode encontrar o histórico dos comandos usados ​​anteriormente usando o historycomando ... experimentá-lo ....

NOTA: Para um usuário específico, todos os comandos usados ​​anteriormente serão armazenados no arquivo de histórico do bash.

karthik G
fonte
1
As outras respostas estão certas. Este está errado.
Scott