Cuando intentas modificar un archivo sin tener permisos de escritura, obtienes un error:
> touch /tmp/foo && Sudo chown root /tmp/foo
> echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Sudoing no ayuda, porque ejecuta el comando como root, pero el Shell maneja la redirección stdout y abre el archivo como usted de todos modos:
> Sudo echo test > /tmp/foo
zsh: permission denied: /tmp/foo
¿Hay una manera fácil de redirigir stdout a un archivo en el que no tiene permiso para escribir, además de abrir un Shell como root y manipular el archivo de esa manera?
> Sudo su
# echo test > /tmp/foo
Sí, usando tee
. Entonces echo test > /tmp/foo
se convierte
echo test | Sudo tee /tmp/foo
También puedes agregar (>>
)
echo test | Sudo tee -a /tmp/foo
Para reemplazar el contenido del archivo con la salida de echo
(como el >
Operador de redireccionamiento de shell).
echo test | Sudo dd of=/tmp/foo
Para escribir en el archivo (al principio, aunque puede usar seek
para generar en diferentes desplazamientos) sin truncar (como el 1<>
Operador Bourne Shell):
echo test | Sudo dd of=/tmp/foo conv=notrunc
Para adjuntar al archivo (como >>
), con GNU dd
:
echo test | Sudo dd of=/tmp/foo oflag=append conv=notrunc
Ver también GNU dd
's conv=excl
para evitar tropezar con un archivo existente (como con set -o noclobber
en shells POSIX) y conv=nocreat
para lo contrario (solo actualiza un archivo existente).
tee
es probablemente la mejor opción, pero dependiendo de su situación, algo como esto puede ser suficiente:
Sudo sh -c 'echo test > /tmp/foo'
Si bien estoy de acuerdo, que | Sudo tee
es la forma canónica, a veces sed (aquí suponiendo que GNU sed
) puede funcionar:
cat sudotest
line 1
Sudo sed -i '1iitest' sudotest && cat sudotest
itest
line 1
Sudo sed -i '$aatest' sudotest && cat sudotest
itest
line 1
atest
-i
modifica el archivo en su lugar. 1i
significa insertar antes de la línea 1. $a
significa agregar después de la última línea.
O copiar a xclipboard:
somecommand | xclip
Sudo gedit sudotest
move cursor to desired place, click middle mouse button to insert, save
He estado dando vueltas en el fondo de mis ideas para un problema similar, y se me ocurrieron las siguientes soluciones:
Sudo uncat
donde uncat
es un programa que lee la entrada estándar y la escribe en el archivo nombrado en la línea de comando, pero todavía no he escrito uncat
.
sudocat
la variante de sudoedit
que aún no he escrito que hace un limpiador Sudo cat
o Sudo uncat
.
o este pequeño truco de usar sudoedit
con un EDITOR que es un script de Shell
#!/bin/sh
# uncat
cat > "$1"
que se puede invocar como |Sudo ./uncat file
o | EDITOR=./uncat sudoedit
pero eso tiene efectos secundarios interesantes.
Use esponja del paquete moreutils. Tiene la ventaja de que no escribe en stdout.
echo test | Sudo sponge /tmp/foo
Use la opción -a para agregar a un archivo en lugar de sobrescribirlo.
El error proviene del orden en que Shell hace las cosas.
La redirección se maneja antes de que el Shell incluso ejecute Sudo
, y por lo tanto se realiza con los permisos del usuario con el que está trabajando actualmente. Dado que no tiene permisos de escritura para crear/truncar el objetivo de la redirección, obtiene un permission denied
error del Shell.
La solución es garantizar que el archivo de salida se cree con la identidad que Sudo
le proporcionó, p. con tee
:
$ generate_output | Sudo tee target_file