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

chowncambiar el propietario; fue solo un ejemploRespuestas:
Sí, utilizando
tee. Entonces seecho test > /tmp/fooconvierteTambién puedes agregar (
>>)fuente
echo test | sudo tee /tmp/foo > /dev/nullPara 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
seekpara 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=exclpara evitar clobbering un archivo existente (como laset -o noclobberde conchas POSIX) yconv=nocreatpor todo lo contrario (sólo actualizar un archivo existente).fuente
echo test | sudo tee /tmp/foo >/dev/nullde descartar la salida.ddno 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.ddpuede ser bastante peligroso (si no quiere decir: devastador) si solo se cometió un pequeño error. Entonces, para los nuevos usuarios, prefiero recomendar elteemétodo para estar en la costa segura.dd of=filesolo (sincount/skip...), es confiable.iflag=fullblockno es necesario porque aquíddescribe en la salida lo que ha leído en la entrada. No importa si no fueron bloques completos.teees probablemente la mejor opción, pero dependiendo de su situación, algo como esto puede ser suficiente:fuente
evallugar 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 teees la forma canónica, a veces sed (aquí suponiendo GNUsed) puede funcionar:-imodifica el archivo en su lugar.1isignifica insertar antes de la línea 1.$asignifica agregar después de la última línea.O copiar a xclipboard:
fuente
sed -irealidad 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 nameo 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 uncatdondeuncates 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.sudocatla variante desudoediteso que aún no he escrito que hace un limpiadorsudo catosudo uncat.o este pequeño truco de usar
sudoeditcon un EDITOR que es un script de shellque puede invocarse como
|sudo ./uncat fileo| EDITOR=./uncat sudoeditpero tiene efectos secundarios interesantes.fuente
cattiene 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.uncatcuando lo tengotee.teetiene 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/nullsi 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
sudoy, 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 deniederror del shell.La solución es garantizar que el archivo de salida se cree con la identidad que se le proporcionó, por
sudoejemplo, contee:fuente