Às vezes estou trabalhando em uma nova caixa (ubuntu) e digito git
e sou alertado:
The program 'git' is currently not installed. You can install it by typing:
apt-get install git-core
Se isso acontecer, sei que posso pegar a última linha fazendo algo como:
!! 2>&1 | tail -n 1
Mas como eu poderia executar o resultado disso ( apt-get install git-core
) com mais facilidade?
eu percebo que eu poderia fazer
`!! 2>&1 | tail -n 1`
mas também existe uma maneira de canalizar a saída e executá-la? Isso não parece funcionar:
!! 2>&1 | tail -n 1 | sh
Além disso, a 2>&1
parte é um pouco complicada, então eu ficaria curioso para saber se existe uma maneira mais fácil de fazer isso acontecer também.
Editar
Também seria aceitável salvar isso em uma variável de alguma forma e depois executar a variável:
!! 2>&1 | tail -n 1 | (store as $mycmd)
$mycmd
Mas também não tenho certeza se conheço uma maneira de inserir stdout
uma variável, pelo menos não com a variável no lado direito do comando.
Responder1
Quando você digita um comando que não existe em seu sistema, o bash executa function command_not_found_handle()
. Nesta função existe uma chamada ao /usr/lib/command-not-found
script que imprime mensagens.
Ubuntu 12.04
Meu primeiro palpite é alterar a fonte deste script para imprimir mensagens , stdout
mas stderr
quando estava lendo a fonte do script, descobri que você pode configurá-lo para apenas perguntar se deseja instalar o pacote ausente.
Se você exportar uma variável, COMMAND_NOT_FOUND_INSTALL_PROMPT
será solicitado que você instale o pacote ausente:
pbm@ubuntu:~$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
pbm@ubuntu:~$ export COMMAND_NOT_FOUND_INSTALL_PROMPT=""
pbm@ubuntu:~$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
Do you want to install it? (N/y)y
sudo apt-get install git
[sudo] password for pbm:
Versões mais antigas do Ubuntu
Infelizmente não há COMMAND_NOT_FOUND_INSTALL_PROMPT
, então posso encontrar algumas outras opções:
1) Instale o pacote 12.04 - não deve ser o problema - são apenas alguns scripts em Python, então deve funcionar (não testado!).
2) Mude stderr
para stdout
. Para fazer isso edite o arquivo /usr/lib/python2.7/dist-packages/CommandNotFound/CommandNotFound.py
e mude stderr
para stdout
nas linhas 237 e 240.
Depois disso você pode usá-lo desta forma:
pbm@ubuntu:~$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
pbm@ubuntu:~$ `git`
//Installation begins
Se você adicionar -y
a opção ao apt-get
comando nas linhas 237 e 240, também poderá usar a sintaxe !! | sh
.
3) Você também pode modificar este script da linha 242 desta forma:
print >> sys.stderr, _("You can install it by typing:")
f = open("%s/.install-missing" % os.path.expanduser('~'),'w')
print >> sys.stderr, "sudo apt-get install %s" % packages[0][0]
print >> f, "sudo apt-get install %s" % packages[0][0]
f.close()
Desta forma você obterá seu comando em file ~/.install-missing
, para poder criar um alias:
alias im="chmod +x ~/.install-missing; ~/.install-missing"
Se você ligar, im
o pacote será instalado.
Responder2
Você estava no caminho certo com:
!! 2>&1 | tail -n 1 | sh
...mas está faltando uma opção paraeh. Considerar:
!! 2>&1 | tail -n 1 | sh -s
E como você provavelmente precisa de acesso root para executar o apt-get, considere:
!! 2>&1 | tail -n 1 | sudo sh -s
Responder3
Você pode fazer algo assim:
!! 2>&1 | tail -n 1 > /tmp/cmd; bash /tmp/cmd; rm /tmp/cmd
Programas interativos não parecem funcionar bem com tubulação porque esperam uma entrada, 'Y' neste caso, mas o descritor de arquivo stdin é fechado assim que o primeiro comando termina.
Responder4
Você pode usar uma variável eval
e uma substituição de comando, acredito (embora não tenha certeza de quão seguro tudo isso seria):
TEST_VAR=$(!! 2>&1 | tail -n 1); eval $TEST_VAR
Estou disposto a provar que estou errado com o que foi dito acima. Estou testando isso em uma máquina Red Hat com um echo
comando em vez da sugestão automática de conclusão do bash, mas o princípio deve ser o mesmo.
No final das contas, seria mais rápido apenas digitar aptitude install git...