Como eu escrevo um apelido de bash que substitui! $ com a última palavra do comando anterior?

1

Eu tenho um script chamado cpodin que copia vários artefatos de compilação para outro diretório. Depois, edito SHA1SUM no diretório de destino.

Por exemplo:

cpodin /foo/bar/baz
vim !$/SHA1SUM

Como faço para o último comando um alias denominado fixsha que não aceita argumentos e edite SHA1SUM no diretório nomeado pelo último argumento do comando anterior? Um alias de

alias fixsha='vim !$/SHA1SUM'

resulta em tentativas de editar !$/SHA1SUM em vez de /foo/bar/baz/SHA1SUM .

    
por Greg Bacon 25.01.2017 / 23:56

1 resposta

2

O Bash não realiza a expansão do histórico após a expansão do alias, portanto, você deve fazê-lo explicitamente usando history , documentado em Bash History Builtins e extraído abaixo.

history -ps args

  • -p
    Perform history substitution on the args and display the result on the standard output, without storing the results in the history list.
  • -s
    The args are added to the end of the history list as a single entry.

Um alias de alias fixsha='vim $(history -p !$)/SHA1SUM' funcionará na maior parte do tempo, mas não como planejado quando !$ se expandir para um caminho que contenha espaços em branco. A adição de aspas duplas ao redor do argumento do caminho protegerá quaisquer escapes no espaço em branco e resultará em vim "/foo/bar\ baz/SHA1SUM" em vez do desejado vim /foo/bar\ baz/SHA1SUM ou seu equivalente vim "/foo/bar baz/SHA1SUM" .

Assim, além da expansão explícita do histórico, eval também é necessário para desdobrar uma camada de cotação.

alias fixsha='eval vim "$(history -p !$)/SHA1SUM"'

Nota: Você pode se surpreender ao saber que as aspas duplas na definição de alias acima são desnecessárias. Isso ocorre porque não há espaços em branco entre o valor expandido de !$ e /SHA1SUM para acionar a divisão de palavras do bash. No entanto, gosto que eles estejam lá para enfatizar a intenção de expandir para um único argumento.

    
por 25.01.2017 / 23:56