A veces estoy trabajando en un cuadro nuevo (ubuntu), escribo git
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 también una manera de canalizar la salida y ejecutarla? Parece que esto no funciona:
!! 2>&1 | tail -n 1 | sh
Además, la 2>&1
pieza es un poco engorrosa, por lo que me gustaría saber si hay una forma más sencilla de hacerlo 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 saber una manera de canalizar stdout
una variable, al menos no con la variable en el lado derecho del comando.
Respuesta1
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 a /usr/lib/command-not-found
un script que imprime mensajes.
ubuntu 12.04
Mi primera suposición fue cambiar la fuente de esta secuencia de comandos para imprimir mensajes stdout
, stderr
pero cuando estaba leyendo la fuente de la secuencia de comandos descubrí que puedes configurarla para que solo te pregunte si deseas instalar el paquete que falta.
Si exporta una variable, COMMAND_NOT_FOUND_INSTALL_PROMPT
se 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
Lamentablemente no existe, COMMAND_NOT_FOUND_INSTALL_PROMPT
así que puedo encontrar algunas otras opciones:
1) Instale el paquete desde 12.04; no debería ser el problema; son solo unos pocos scripts en Python, por lo que debería funcionar (¡no probado!).
2) Cambiar stderr
a stdout
. Para hacerlo, edite el archivo /usr/lib/python2.7/dist-packages/CommandNotFound/CommandNotFound.py
y cámbielo stderr
a stdout
las líneas 237 y 240.
Después de eso puedes 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 -y
una opción al apt-get
comando en las líneas 237 y 240, también puede usar la sintaxis !! | sh
.
3) También puedes 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ás tu comando en el archivo ~/.install-missing
, por lo que podrás crear un alias:
alias im="chmod +x ~/.install-missing; ~/.install-missing"
Si llama, im
se instalará el paquete.
Respuesta2
Estabas en el camino correcto con:
!! 2>&1 | tail -n 1 | sh
...pero te falta una opción parash. Considerar:
!! 2>&1 | tail -n 1 | sh -s
Y como probablemente necesites acceso root para ejecutar apt-get, considera:
!! 2>&1 | tail -n 1 | sudo sh -s
Respuesta3
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 del archivo estándar se cierra tan pronto como termina el primer comando.
Respuesta4
Puede usar una variable eval
y una 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 que me demuestren que estoy equivocado con lo anterior. Estoy probando esto en una máquina Red Hat con un echo
comando 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 simplemente escribir aptitude install git...