Não é possível obter “eco !!” para trabalhar no bash a partir de um script salvo

2

Eu estou tentando escrever um script simples para pegar um comando anterior que foi (acidentalmente) escrito em um layout diferente do inglês, converter tudo em símbolos corretos e executá-lo . Estou usando Bash 4.3.11 .

Meu código atual se parece com isso (eu não sou um programador, apenas estou tentando aprender isso para uma usabilidade geral):

echo !! | sed -e "y/first-set-of-symbols/second-set-of-symbols/" | bash

O problema é que, quando executo o script de um arquivo, recebo o seguinte: " bash: line 1: !!: comando não encontrado ", mas quando eu apenas copio, colo o comando inteiro faz o que se espera que faça; se eu mudar a parte do eco para algo como "echo test-command" no arquivo de script, isso funciona quando eu executo o script também.

Alguém poderia me ajudar a entender por que !! não está funcionando a partir de um script aqui? É suposto?

Também estou aberto a sugestões sobre como fazer o que estou tentando fazer de uma maneira melhor / mais eficiente / mais elegante.

(Eu não estou usando o tr, porque, aparentemente, ele não funciona com Unicode, pelo menos é o que dizem - pelo menos não funciona para mim.)

    
por Unco Lober 23.10.2015 / 10:06

2 respostas

2

O atalho !! é válido apenas para uma sessão interativa. Em todas as outras situações, é tratado como um par literal de caracteres.

Copie e cole isto para ver o que está acontecendo:

cat >/tmp/pling.sh <<x
#!/bin/bash
echo hello, world
echo you said !!
x

# Now make the file executable
chmod a+x /tmp/pling.sh

# Now run it
/tmp/pling.sh
    
por 23.10.2015 / 11:16
0

O histórico de comandos não está ativado em scripts. Mesmo se você ativá-lo, o script não terá acesso ao histórico do shell interativo que o chamou.

Em vez de escrever um script, crie uma função e coloque-a no seu .bashrc .

Além disso, em vez de executar o comando em uma instância separada do bash, você provavelmente deve usar o eval builtin para executá-lo no mesmo contexto (as mesmas variáveis do shell em particular).

Sua abordagem com expansão de histórico funciona apenas para comandos simples; comandos contendo caracteres especiais resultarão em erros de sintaxe ou outro comportamento não intencional. Use o fc incorporado para acessar o histórico programaticamente.

reexecute () {
  eval "$(fc -l -1 | sed …)"
}
    
por 23.10.2015 / 15:15