Ejecutar una línea de comandos con un sudo

Ejecutar una línea de comandos con un sudo

Por ejemplo, si quiero crear un archivo e ingresar texto en una línea, puedo redirigir la salida a un archivo con el uso del >operador:

echo "something" > /path/foobar

pero si no tengo acceso a la carpeta /path/y necesito privilegios sudo, ¿cómo puedo lograr este mismo comando como un usuario normal con derechos sudo?

Lo intenté

sudo echo "something" > /path/foobar

pero eso no funciona, porque el sudo solo cuenta para la editparte derecha pero no para
la>

Claro, podría convertirme en root antes con sudo suo usar teeen su lugar:

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 alguna manera de "reciclar" la última línea y simplemente agregarla sudoal frente?

Respuesta1

No puede simplemente permanecer sudodelante de 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.). Así que 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, bashfcincorporadote 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 las variables de entorno (solo las que sudoconserva, claro está), pero no las variables internas del shell. Las opciones de Shell (p. ej. kshglob) y otras configuraciones comenzarán desde el valor predeterminado.

El mismo comando² funciona en zsh y ksh, aunque ATT ksh93 requiere que se pase el número firsty a ³ (que también funciona en bash, zsh y pdksh/mksh):lastfc

sudo zsh -c "$(fc -ln -1)"
sudo ksh -c "$(fc -ln -1 -1)"
sudo "$0" -c "$(fc -ln -1 -1)"

El uso $0para designar el ejecutable del shell en ejecución funciona solo si el shell se invocó a través de $PATH y $PATH no ha cambiado, o mediante 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: sudoes para comandos potencialmente peligrosos. ¡No hagas que su uso sea demasiado fácil!

¹ 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 nada parecido a bash $BASH; $0solo funciona cuando es una ruta absoluta o cuando no contiene barra diagonal y la ruta de búsqueda del comando no ha cambiado.
³ es un alias de ATT ksh pero es igual de bueno. fchist

Respuesta2

Si desea rehacer el mismo comando consudo!!después de hacer un comando como este:

echo "something">/path/file

Luego utiliza la sintaxis de reemplazo global para recuperar el comando:

!!:gs/>/|sudo tee -a /

Utilice un espacio después del-aparámetro.

Este es el equivalente asudo!!pero le ayuda a evitar las restricciones de sudo para < y >. Porque sudo no te permite usar [<, >].


Para evitar las restricciones de sudo en general para redirecciones, puedes usarlo así:

echo "something" | sudo tee myfile

El comando tee le permitirá leer desde la entrada estándar y escribir en archivos y salidas estándar

Si desea repetir el comando y agregar un texto al archivo, el comando tee tiene la-aopción para agregar. Entonces podrías recordar el comando con

sudo !!

y el texto se agregará al archivo

ejemplo:

echo "something" | sudo tee -a /path/file
sudo !!

Respuesta3

Parece ser tan simple como sudo sh -c "!!":

$ cd /
$ echo hello > foo
bash: foo: Permission denied
$ sudo sh -c "!!"
sudo sh -c "echo hello > foo"
$ ls -l foo
-rw-r--r-- 1 root root 6 Jun 20 16:21 foo

información relacionada