¿Cuál es la forma más fácil de ejecutar texto desde la cola en la línea de comando?

10

A veces estoy trabajando en un nuevo cuadro (ubuntu) gity escribo y recibo una alerta:

The program 'git' is currently not installed.  You can install it by typing:
apt-get install git-core

Si eso sucede, sé que puedo tomar la última línea haciendo algo como:

!! 2>&1 | tail -n 1

Pero, ¿cómo podría ejecutar el resultado de eso ( apt-get install git-core) más fácilmente?

Me doy cuenta de que puedo hacer

`!! 2>&1 | tail -n 1`

pero, ¿hay alguna manera de canalizar la salida y ejecutarla? Parece que esto no funciona:

!! 2>&1 | tail -n 1 | sh

Además, la 2>&1parte es un poco engorrosa, por lo que me gustaría saber si hay una manera más fácil de hacer que eso suceda también.

Editar

También sería aceptable guardar esto en una variable de alguna manera, y luego ejecutar la variable:

!! 2>&1 | tail -n 1 | (store as $mycmd)
$mycmd

Pero tampoco estoy seguro de conocer una forma de canalizar stdoutuna variable, al menos no con la variable en el lado derecho del comando.

cwd
fuente

Respuestas:

8

Cuando escribe un comando que no existe en su sistema, bash ejecuta la función command_not_found_handle(). En esta función hay una llamada al /usr/lib/command-not-foundscript que imprime mensajes.

Ubuntu 12.04

Mi primera aproximación a la fuente de cambio de esta secuencia de comandos para imprimir mensajes a stdoutsu lugar stderr, pero cuando estaba leyendo fuente de escritura que encontró que puedes configurarlo para que sólo pregunte si desea instalar el paquete faltante.

Si exporta la variable, COMMAND_NOT_FOUND_INSTALL_PROMPTse le pedirá que instale el paquete que falta:

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: 

Versiones anteriores de Ubuntu

Desafortunadamente no hay, COMMAND_NOT_FOUND_INSTALL_PROMPTasí que puedo encontrar algunas otras opciones:

1) Instale el paquete desde 12.04, no debería ser el problema, solo son unos pocos scripts en Python, por lo que debería funcionar (¡no probado!).

2) Cambiar stderra stdout. Para hacerlo, edite el archivo /usr/lib/python2.7/dist-packages/CommandNotFound/CommandNotFound.pyy cambie stderra stdouten las líneas 237 y 240.

Después de eso, puede usarlo de esta manera:

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

Si agrega la -yopción al apt-getcomando en las líneas 237 y 240, también podría usar la sintaxis !! | sh.

3) También puede modificar este script desde la línea 242 de esta manera:

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()

De esta manera, obtendrá su comando en el archivo ~/.install-missing, por lo que puede crear un alias:

alias im="chmod +x ~/.install-missing; ~/.install-missing"

Si llama impaquete se instalará.

pbm
fuente
Hmm, esto se veía muy bien, pero en realidad no parece funcionar en 11.10 onírico, /usr/lib/command-not-foundpero no tiene ninguna referencia a COMMAND_NOT_FOUND_INSTALL_PROMPT... ¿pensamientos?
cwd
Ok, parece que esta es una característica que será parte de 12.04 precisa, ( package-import.ubuntu.com/diffs/command-not-found ). Supongo que todavía necesito una solución para versiones anteriores.
cwd
@cwd: Actualicé mi respuesta ...
pbm
3

Estabas en el camino correcto con:

!! 2>&1 | tail -n 1 | sh

... pero te falta una opción para sh . Considerar:

!! 2>&1 | tail -n 1 | sh -s

Y dado que probablemente necesite acceso de root para ejecutar apt-get, considere:

!! 2>&1 | tail -n 1 | sudo sh -s
ctt
fuente
Esto no funciona sh y sh -s hacen lo mismo, al menos en este caso.
Deepak Mittal el
1

Puedes hacer algo como esto:

!! 2>&1 | tail -n 1 > /tmp/cmd; bash /tmp/cmd; rm /tmp/cmd

Los programas interactivos no parecen funcionar bien con la tubería porque espera una entrada, 'Y' en este caso, pero el descriptor de archivo stdin se cierra tan pronto como se completa el primer comando.

Deepak Mittal
fuente
0

Puede usar una variable evaly la sustitución de comandos, creo (aunque no estoy seguro de qué tan seguro sería todo esto):

TEST_VAR=$(!! 2>&1 | tail -n 1); eval $TEST_VAR

Estoy dispuesto a demostrar que estoy equivocado con lo anterior. Estoy probando esto en una máquina Red Hat con un echocomando en lugar de la sugerencia automática de finalización de bash, pero el principio debería ser el mismo.

Al final del día, sería más rápido escribir aptitude install git ...

Webtoe
fuente