Por ejemplo, si quiero crear un archivo e ingresar texto en una línea, puedo redirigir la salida a un archivo con el uso de >
operador:
echo "something" > /path/foobar
pero si no tengo acceso a la carpeta /path/
y necesito privilegios de sudo, ¿cómo puedo lograr este mismo comando como un usuario normal con derechos de sudo?
Lo intenté
sudo echo "something" > /path/foobar
pero eso no funciona, porque el sudo solo cuenta para el edit
pero no para la parte derecha
del >
Claro, podría convertirme en root antes con sudo su
o usa tee
en cambio:
echo "something" | sudo tee /path/foobar
Pero me gustaría encontrar una solución en la que pueda trabajar con la última línea como reemplazo a través de
sudo !!
¿No hay una manera de "reciclar" la última línea y simplemente agregar sudo
? en frente?
Respuesta aceptada:
No puedes simplemente pegar sudo
frente a un comando de shell, debe invocar un shell para evaluar ese comando nuevamente (hacer cosas como expandir variables, abrir archivos para operadores de redirección, etc.). Entonces eso es
sudo bash -c !!
excepto que esto no funciona del todo, porque !!
interpola el texto del comando anterior, caracteres especiales y todo. Debe recuperar el texto del comando como una cadena y pasarlo como argumento a sh
. Afortunadamente, el fc
de bash incorporado te permite hacer eso¹.
sudo bash -c "$(fc -ln -1)"
O incluso, para asegurarse de invocar la misma versión de bash que se está ejecutando actualmente:
sudo "$BASH" -c "$(fc -ln -1)"
Tenga en cuenta que dado que el comando se ejecuta en un proceso de shell separado, hereda variables de entorno (solo las que sudo
conserva, mente), pero no variables internas de shell. Opciones de shell (por ejemplo, kshglob
) y otras configuraciones comenzarán desde el valor predeterminado.
El mismo comando² funciona en zsh y ksh, aunque ATT ksh93 requiere ambos first
y last
número a pasar a fc
³ (que también funciona en bash, zsh y pdksh/mksh):
sudo zsh -c "$(fc -ln -1)"
sudo ksh -c "$(fc -ln -1 -1)"
sudo "$0" -c "$(fc -ln -1 -1)"
Usando $0
para designar el ejecutable del shell en ejecución solo funciona si el shell se invocó a través de $PATH y $PATH no ha cambiado, o a través de una ruta absoluta.
Aquí hay otro método en zsh que es un poco más claro pero más largo:
sudo zsh -c $history[$[HISTCMD-1]]
Una última palabra de advertencia:sudo
es para comandos potencialmente peligrosos. ¡No hagas que sea demasiado fácil de usar!
¹ Hay algunos espacios en blanco adicionales al principio y la sustitución del comando elimina las nuevas líneas al final, pero a la sintaxis del shell no le importa eso.
² No creo que zsh o ksh tengan algo parecido a $BASH
de bash; $0
solo funciona cuando es una ruta absoluta o cuando no contiene una barra oblicua y la ruta de búsqueda del comando no ha cambiado.
³ fc
es un alias para hist
en ATT ksh pero eso es igual de bueno.