O que significa! #: 3 em um comando shell

29

O guia de instalação do ack sugere a instalação do script ack usando este comando:

curl http://beyondgrep.com/ack-2.14-single-file > ~/bin/ack && chmod 0755 !#:3 

Suponho que !#:3no final seja algum tipo de referência posterior, mas o que isso significa? Existe um equivalente no zsh? O Google não foi útil.

Matt Pfefferle
fonte
5
Assumindo festança; man bashe procure por HISTORY EXPANSION
Jeff Schaller
1
Isso significa que meu gato atravessou o teclado em um momento muito ruim.
IQAndreas
@IQAndreas: Bem, é um comando válido, então seu gato deve ser inteligente o suficiente para derrotar o detector de digitação de gatos . Claramente, este não é um gato inútil. :-) ⁠
G-Man diz 'Reinstate Monica'

Respostas:

32

Essa é uma sintaxe especial, expandida pelo bash. Também funciona para o zsh.

De acordo com a página do manual do bash (seção HISTORY EXPANSION), o padrão se expande da seguinte forma:

  • O designador de evento !# refere-se a toda a linha de comando digitada até o momento, que écurl http://beyondgrep.com/ack-2.14-single-file > ~/bin/ack && chmod 0755
  • :divide entre o designador de eventos (neste caso, a linha inteira) e o designador de palavras (seleciona uma sub-parte)
  • o designador de palavras 3 que seleciona a terceira palavra / argumento (a contagem de palavras começa em zero), neste caso ~/bin/ack.

A linha de comando final (geralmente exibido antes executado) é: curl http://beyondgrep.com/ack-2.14-single-file > ~/bin/ack && chmod 0755 ~/bin/ack.

Para detalhes, consulte o manual do bash ou muito semelhante ao manual do zsh

jofel
fonte
7
Não posso deixar de me perguntar: quem pensou que esse recurso seria uma boa idéia?
Rhymoid
3
@Rhymoid, eu não uso !#muito, mas !!, !$, !*, !sud:pe muitos outros são todos extremamente útil e eu usá-los o tempo todo. Confira unix.stackexchange.com/a/67/135943
Wildcard
11

Em bash, é a substituição do histórico (todas as substituições do histórico começam com !). Especificamente, !#significa tudo na linha de comando até agora, e a adição ': 3' significa a terceira palavra (contagem inicial em 0).

Portanto, o comando acima se traduz !#:3em ~/bin/ack.

Brian
fonte