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
shell
permissions
io-redirection
sudo
io
Michael Mrozek
fuente
fuente
chown
cambiar el propietario; fue solo un ejemploRespuestas:
Sí, utilizando
tee
. Entonces seecho test > /tmp/foo
convierteTambién puedes agregar (
>>
)fuente
echo test | sudo tee /tmp/foo > /dev/null
Para reemplazar el contenido del archivo con la salida de
echo
(como el>
operador de redirección de shell).Para escribir en el archivo (al principio, aunque puede usar
seek
para generar en diferentes desplazamientos) sin truncar (como el1<>
operador de shell Bourne):Para adjuntar al archivo (como
>>
), con GNUdd
:Ver también GNU
dd
'sconv=excl
para evitar clobbering un archivo existente (como laset -o noclobber
de conchas POSIX) yconv=nocreat
por todo lo contrario (sólo actualizar un archivo existente).fuente
echo test | sudo tee /tmp/foo >/dev/null
de descartar la salida.dd
no es confiable para eso a menos que esté usando opciones oscuras solo de GNUiflag=fullblock oflag=fullblock
, que eliminan la elegancia de esta respuesta. Yo me quedo contee
.dd
puede ser bastante peligroso (si no quiere decir: devastador) si solo se cometió un pequeño error. Entonces, para los nuevos usuarios, prefiero recomendar eltee
método para estar en la costa segura.dd of=file
solo (sincount
/skip
...), es confiable.iflag=fullblock
no es necesario porque aquídd
escribe en la salida lo que ha leído en la entrada. No importa si no fueron bloques completos.tee
es probablemente la mejor opción, pero dependiendo de su situación, algo como esto puede ser suficiente:fuente
eval
lugar de un simplesh -c
; -i, que cambiará su directorio de trabajo; ejecutar todo el comando como root, lo que podría cambiar su comportamiento o introducir un riesgo innecesario. ¿Por qué esto alguna vez recibió un voto positivo?Si bien estoy de acuerdo, esa
| sudo tee
es la forma canónica, a veces sed (aquí suponiendo GNUsed
) puede funcionar:-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:
fuente
sed -i
realidad no modifica el archivo en su lugar : crea un archivo temporal y lo renombra al salir. Por lo tanto, no podrá hacer algo comotail -f ...
en el archivo original y ver la salida usandosed -i ...
mientras la tubería se está ejecutando-i creates a new file of same name
o hay algo más compacto? Supongo que me gustain place
, porque explica eli
. La página de manual de GNU-sed lo llama en su lugar también y el largo de la bandera es--in-place
.He estado dando vueltas en el fondo de mis ideas para un problema similar, y se me ocurrieron las siguientes soluciones:
sudo uncat
dondeuncat
es un programa que lee la entrada estándar y la escribe en el archivo nombrado en la línea de comando, pero aún no lo he escritouncat
.sudocat
la variante desudoedit
eso que aún no he escrito que hace un limpiadorsudo cat
osudo uncat
.o este pequeño truco de usar
sudoedit
con un EDITOR que es un script de shellque puede invocarse como
|sudo ./uncat file
o| EDITOR=./uncat sudoedit
pero tiene efectos secundarios interesantes.fuente
cat
tiene una lista de archivos para con gato innata, por lo tanto, UNCAT debe tener una lista de archivos a la ONU con gato inate a. Tendría que usar magia para decidir cuánto poner en cada archivo. Nombre alternativo incluyendog
,to-file
,redirect
.uncat
cuando lo tengotee
.tee
tiene el inconveniente trivial en el que escribe su stdin en su stdout, que se mitiga trivialmente al redirigir el stdout/dev/null
. Otras alternativas incluyendd of=/tmp/foo
(mencionado en otra respuesta), que escribe información de estado en stderr, ycp /dev/stdin /tmp/foo
.Use esponja del paquete moreutils. Tiene la ventaja de que no escribe en stdout.
Use la opción -a para agregar un archivo en lugar de sobrescribirlo.
fuente
/dev/null
si fuera un problemaEl error proviene del orden en que el shell hace las cosas.
La redirección se maneja incluso antes de que se ejecute el shell
sudo
y, por lo tanto, se realiza con los permisos del usuario con el que está trabajando actualmente. Como no tiene permisos de escritura para crear / truncar el objetivo de la redirección, obtiene unpermission denied
error del shell.La solución es garantizar que el archivo de salida se cree con la identidad que se le proporcionó, por
sudo
ejemplo, contee
:fuente