¿Cómo establecer permisos de archivo específicos al redirigir la salida?


12

Probablemente sea un duplicado, pero todas mis búsquedas están generando preguntas sobre errores de permiso denegado.

Estoy ejecutando un comando en un shell bash. Quiero redirigir la salida para agregarla a un archivo que probablemente no exista en la primera ejecución. Quiero establecer un modo de permisos de archivo específico si la redirección de salida tiene que crear este archivo. ¿Hay alguna manera de hacer esto con un comando?

Por ejemplo, podría intentar

foo >> /tmp/foo.log 0644

¿Dónde 0644están los permisos con los que quiero foo.logterminar? La mayoría de los comandos con los que he experimentado en bash terminan interpretando 0644como un argumento adicional para foo.

Tengo la sensación de que esto llevará un segundo comando a chmodlos permisos antes o después de escribirle.

Estoy usando GNU bash 4.2.25 y Ubuntu 12.04, si eso hace la diferencia, se prefieren las respuestas generales.

Respuestas:


5

Por lo que sé, no hay forma de hacerlo mientras se canaliza, un script simple podría ser la mejor solución.

if [ -e /tmp/foo.log ]; then
    foo >> /tmp/foo.log
else
    foo >> /tmp/foo.log
    chmod 0644 /tmp/foo.log
fi

Gracias Slowki, esa fue mi corazonada también. Lo dejaré abierto durante unos días, con la esperanza de atraer a un gurú para iluminarnos.
Patrick M

3
El problema con este enfoque es que crea una ventana de tiempo corto cuando los permisos en el archivo son incorrectos. No lo usaría si el objetivo es proteger los datos confidenciales.
proski

1
Esta respuesta funciona, hasta donde llega, pero @proski tiene razón: las umaskrespuestas son mejores, y una de ellas debería ser aceptada.
Scott

15

Sé que es una vieja pregunta, pero quería agregar mis dos centavos.

Tuve la misma idea y se me ocurrió una solución similar a BowlesCR . El problema con su solución fue que mi comando ( foo) no funcionaría si cambiara la umask antes de ejecutarla, así que esta es mi opinión sobre el problema:

foo | ( umask 0033; cat >> /tmp/foo.log; )

Aquí, umasksolo afecta la redirección a foo.logen la subshell. Todo lo demás no se ve afectado.

Un poco complicado, pero funciona.


Muy agradable y efectivo :) Simplemente no se puede usar con la redirección de stderr en la parte superior de stdout redir.
Orsiris de Jong

5

Sin una verdadera secuencia de comandos, puede encadenar un poco:

touch /tmp/foo.log; chmod 0644 /tmp/foo.log; foo >> /tmp/foo.log

Efectivamente similar a la respuesta de Slowki , pero condensado en una sola línea.

Lo único que se me ocurre es jugar con la umask. Lo mejor es hacer esto en una subshell para que no contamine el entorno actual:

(umask 0033 && foo >> /tmp/foo.log)

Sin embargo, hay dos problemas con eso.

  1. Umask no puede aumentar los permisos por encima del nivel especificado en la creat()llamada al sistema (0666 parece ser lo que usa Bash).
  2. Esto no cambiará los permisos en un archivo existente (porque se umaskaplica solo a la creación de archivos ).

Todavía soy lo suficientemente nuevo para * nix que el umask sigue siendo un poco mágico para mí. Gracias por el consejo, me aseguraré de leerlo.
Patrick M

Hmm ... Todavía permite que un proceso sin privilegios abra el archivo y luego lea su contenido.
Feuermurmel

(1) Felicitaciones por encontrar un uso interesante y útil de cat. (Aunque esto no sigue el patrón estándar de usos inútiles de  cat.) (2) Supongo que usted quiso decir que bash está predeterminado en el modo  0666 al crear archivos, por lo que edité su respuesta para decirlo. (Mira esto ,  esto   ... (Continúa)
Scott

(Cont.) ... y  esto .) Y la pregunta menciona específicamente el modo 0644. Por lo tanto, un umaskvalor de 22, 23 o 32 también funcionaría, en este contexto (no es necesario utilizar cero a la izquierda; cuando los modos y  umaskvalores se especifican numéricamente, siempre se interpretan como octales).  22 es más comúnmente usado convencionalmente.
Scott

@Feuermurmel: ¿Y qué? La pregunta requiere explícitamente el modo 644. Tenemos que suponer que el OP sabe que 644 significa legible en todo el mundo y tiene la intención de hacer pública su información.
Scott

1

Cuando la redirección establece los permisos incorrectos, por ejemplo:

$ rm capture.*
$ perl -e 'print STDERR "$$ STDERR\n"; print STDOUT "$$ STDOUT\n"' \
                            >> capture.STDOUT 2>> capture.STDERR
$ perl -e 'print STDERR "$$ STDERR\n"; print STDOUT "$$ STDOUT\n"' \
                            >> capture.STDOUT 2>> capture.STDERR
$ ls -l capture.*
-rw-rw-rw- 1 jcookinf jcookinf 22 Jun 12 10:38 capture.STDERR
-rw-rw-rw- 1 jcookinf jcookinf 22 Jun 12 10:38 capture.STDOUT
$ cat capture.*
215 STDERR
216 STDERR
215 STDOUT
216 STDOUT

Creo que puede usar algo como lo que xynomorf le dio, y abordar la preocupación más fuerte de Orsiris de Jong con una ligera modificación para usar la sustitución del proceso bash .

$ rm capture.*
$ perl -e 'print STDERR "$$ STDERR text\n"; print STDOUT "$$ STDOUT text\n"' \
            > >(umask 0033; cat >> capture.STDOUT) 2> >(umask 0033; cat >> capture.STDERR)
$ perl -e 'print STDERR "$$ STDERR text\n"; print STDOUT "$$ STDOUT text\n"' \
            > >(umask 0033; cat >> capture.STDOUT) 2> >(umask 0033; cat >> capture.STDERR)
$ ls -l capture.*
-rw-r--r-- 1 jcookinf jcookinf 32 Jun 12 10:43 capture.STDERR
-rw-r--r-- 1 jcookinf jcookinf 32 Jun 12 10:43 capture.STDOUT
$ cat capture.*
233 STDERR text
238 STDERR text
233 STDOUT text
238 STDOUT text

Naturalmente, utilícelo umask 0077para obtener el modo 600 y prohibir que otros usuarios vean el contenido.


0

Si desea redirigir a un script, a diferencia de umask, con la sustitución de procesos y installtambién puede establecer el bit de ejecución:

install -m 755 <(echo commands go here) newscript

<()coloca la salida en un archivo temporal, consulte Proceso de sustitución

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.