Histórico do Bash no script: '! #: *'

4

Estive lendo os guias de estudo do LPIC -1 .

echo "This is a sentence. " !#:* !#:1->text3

Estou tendo problemas para entender como a linha de código acima repete o comando echo várias vezes. Eu sei que ele está usando um recurso do histórico de bash , mas não consigo encontrar nenhuma documentação sobre !#:* ou !#:1 . Alguém poderia explicar isso para mim?

    
por chthonous 11.08.2014 / 17:55

4 respostas

11

Sim, isso está usando o histórico. !# é um designador do evento histórico que se refere a toda a linha de comando digitada até agora. :* é um designador de palavra (intervalo) que se refere a todas as palavras, exceto a 0ª. Então, depois de ter digitado echo "This is a sentence. " , então !#:* expande para "This is a sentence.  " . E x-y (onde x e y são inteiros) é um designador de palavra (intervalo) que se refere ao número da palavra x através do número da palavra y . Se y for omitido ( x- ), isto é interpretado como significando o número da palavra x através da segunda para a última palavra. Então, depois que sua “linha de comando inteira digitada até agora”

echo "This is a sentence. " "This is a sentence. "

então !#:1- expande para "This is a sentence. " , porque cada uma das strings "This is a sentence. " citadas conta como uma palavra, e assim !#:1- é equivalente a !#:1 (apenas palavra número 1). Então você acaba com

echo "This is a sentence. " "This is a sentence. " "This is a sentence. " >text3

O fato de que - e > aparecem juntos no comando é apenas uma confusão; eles não interagem. E o fato de que “Isto é uma frase” é citado obscurece o que está acontecendo; se você disse

echo This is a sentence. !#:* !#:1-

expandir-se-ia para

echo This is a sentence. This is a sentence. !#:1-

e daí para

echo This is a sentence. This is a sentence. This is a sentence. This is a

(porque !#:1- se expande para a palavra número 1 até a segunda para a última palavra.)

    
por 11.08.2014 / 18:25
4

Uma boa documentação sobre a ficha de história do bash de Peter Krumins pode ser encontrada aqui .

Como você entendeu !# , apenas explicamos :* e :1 .

  • * : refere-se a todas as palavras, exceto as zeroth.
  • x- : refere-se às palavras de x à segunda à última palavra.

Então, seu comando:

echo "This is a sentence. " !#:* !#:1-
  • !#:* obtém tudo, menos o zeroth, por isso obtém "This is a sentence. " , seu comando se torna echo "Esta é uma frase." Esta é uma frase. ".

  • !#:1- obtém a palavra de 1 a segunda para a última palavra, significando "This is a sentence. " novamente, seu comando se torna echo "Esta é uma frase." "Esta é uma frase." sentença. "

por 11.08.2014 / 18:24
3

Como @glennjackman aponta, tudo isso está coberto no manual bash. Pesquise na página do manual por HISTORY EXPANSION .

  • !# é um designador de evento que significa "toda a linha de comando digitada até agora". No seu exemplo, é echo "This is a sentence. " , incluindo um espaço final após a aspa dupla final.

  • : separa o designador de evento ( !# ) do palavra designador ( * ).

  • * é um designador de palavras que significa "todas as palavras do evento, exceto a zeroth"

Então echo "This is a sentence. " !#:* se expande para

echo "This is a sentence. " "This is a sentence. " $

(o cifrão é meu, indicando o fim do espaço em branco) que ecoa

This is a sentence.  This is a sentence. $

para o terminal (novamente, o cifrão é meu, indicando o fim do espaço em branco).

O segundo designador de evento : o par palavra designador ( !#:1- ) funciona de maneira semelhante (mas lembre-se de que ele precisa lidar com o fato de que o comando A linha foi expandida consideravelmente agora que o primeiro par de designador foi avaliado).

    
por 11.08.2014 / 18:40
1

Eu experimentei com !#:* e !#:1 . Não encontrei muitas fontes on-line para isso, mas tenho certeza de que você introduziu um echo "Sample text" e, em seguida, você pode usar !#:* !#:1 !#:2->text e o! #: * Armazenará temporariamente o conteúdo da string lá. Não tenho certeza se é um tipo de declaração condicional, pois não consegui encontrar muitos recursos, mas parece que isso é útil quando você está tentando codificar a mesma coisa e deseja salvar as teclas digitadas. Eu tentei isso no bash:

echo "test" !#:* !#:1 !#:2 !#:3 !#:4->test1

Isso é o que eu recebo no test1:

test test test test test test

Ferramenta muito bacana.

    
por 11.08.2014 / 18:05