Forma estándar de duplicar los permisos de un archivo

9

Estoy tratando de encontrar una forma POSIX estándar para duplicar los permisos de un archivo a otro archivo. En un sistema GNU esto es fácil:

[alexmchale@bullfrog ~]$ ls -l hardcopy.*
-rw-r--r-- 1 alexmchale users 2972 Jul  8 20:40 hardcopy.1
---------- 1 alexmchale users 2824 May 14 13:45 hardcopy.4
[alexmchale@bullfrog ~]$ chmod --reference=hardcopy.1 hardcopy.4
[alexmchale@bullfrog ~]$ ls -l hardcopy.*
-rw-r--r-- 1 alexmchale users 2972 Jul  8 20:40 hardcopy.1
-rw-r--r-- 1 alexmchale users 2824 May 14 13:45 hardcopy.4

Desafortunadamente, el indicador de referencia a chmod es una opción no estándar. Entonces eso está fuera para mis propósitos. Preferiría que fuera de una sola línea, pero eso no es necesario. En definitiva, debe estar en la sintaxis sh POSIX.

Alex
fuente

Respuestas:

6

Una tentación es analizar ls. Evita esa tentación .

Lo siguiente parece funcionar, sin embargo, está lleno de Kluge. Se basa en cpretener los permisos del archivo de destino. Para esta demostración, el archivo "plantilla" aún no debe existir.

  • Copie el archivo con los permisos que desea a un nuevo archivo
  • Copie el archivo que desea cambiar al archivo creado en el paso anterior
  • Elimine el archivo original que desea cambiar.
  • Cambie el nombre del archivo intermedio al nombre del archivo que se va a cambiar.

Manifestación:

$ echo "contents of has">has
$ echo "contents of wants">wants
$ chmod ug+x has     # just so it's different - represents the desired permissions
$ cp has template
$ cat has
contents of has
$ cat wants
contents of wants
$ cat template
contents of has
$ ls -l has wants template
-rwxr-xr-- 1 user user 16 2010-07-31 09:22 has
-rwxr-xr-- 1 user user 16 2010-07-31 09:23 template
-rw-r--r-- 1 user user 18 2010-07-31 09:22 wants
$ cp wants template
$ ls -l has wants template
-rwxr-xr-- 1 user user 16 2010-07-31 09:22 has
-rwxr-xr-- 1 user user 18 2010-07-31 09:24 template
-rw-r--r-- 1 user user 18 2010-07-31 09:22 wants
$ cat template
contents of wants
$ rm wants
$ mv template wants
$ ls -l has wants
-rwxr-xr-- 1 user user 16 2010-07-31 09:22 has
-rwxr-xr-- 1 user user 18 2010-07-31 09:24 wants
$ cat has
contents of has
$ cat wants
contents of wants
Dennis Williamson
fuente
Ahora ese es un enfoque interesante. Voy a probar esto y ver qué tan bien funciona en varios servidores. Me parece que hará el truco.
Alex
@Alex: asegúrese de probarlo también con la propiedad del archivo, si eso es una preocupación.
Dennis Williamson
El primer comando cp cp has template, debería usarse cp -ppara preservar el modo y los atributos de propiedad.
Mernst
@mernst: Eso solo es necesario para el primero cpsi el propietario / grupo del archivo (por ejemplo, "usuario") es diferente del que realiza la copia (por ejemplo, root).
Dennis Williamson
@ Dennis Willamson: OK, pero esa es una posibilidad y no veo ningún inconveniente en usarla cp -pallí.
Mernst
10

Puede usar el statcomando para obtener el permiso de archivo:

  • Sintaxis de Mac OS X (BSD):

    chmod `stat -f% A fileWithPerm` fileToSetPerm

  • Sintaxis de Linux (no estoy seguro):

    chmod `stat -c% a fileWithPerm` fileToSetPerm

El símbolo ` es una cita inversa.

Studer
fuente
1
No creo que statsea ​​requerido por POSIX. A menudo no está disponible.
Dennis Williamson
stat (línea de comando) no es POSIX y no es portátil. Dennis ++
jim mcnamara
0

Las utilidades ACL getfacl y setfacl se pueden usar para este propósito, pero no sé si este POSIX cumple lo suficiente. Funciona al menos en FreeBSD 8.0 y Linux, pero por otro lado uno podría tener que instalar las utilidades de ACL.

Desde la página del manual:

getfacl file1 | setfacl -b -n -M - file2
Copy ACL entries from file1 to file2.

Creo que getfacl y setfacl también pueden operar con permisos de archivo estándar además de los ACL.

Janne Pikkarainen
fuente
Las ACL y demás están definidas por POSIX son específicas de la implementación, por lo que no es necesario para el cumplimiento.
Dennis Williamson
0

cp -p preservará los permisos de archivo.

usuario31894
fuente
1
Es por eso que la técnica en mi respuesta (de no usar -p) funciona para lo que quiere el OP, que es duplicar los permisos para un archivo diferente , no un duplicado del archivo.
Dennis Williamson
0

Una forma sencilla y portátil no es una utilidad estándar: necesitaría llamar a stat () en el archivo de plantilla, luego a chmod () en los archivos de destino. Esto significa usar un lenguaje como C u otro lenguaje ampliamente utilizado como perl.

Los permisos de acceso a archivos se especifican en el miembro struct stat st_mode por 0007777 bits. La solución de Dennis es correcta, si es un poco pesado en E / S, por lo que para archivos realmente grandes puede fallar:

cp has template

Considere este ejemplo no listo para la producción:

#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

mode_t 
getperm(const char *template_file)
{
    struct stat st;
    if(stat(template_file, &st)==-1)
    {
       perror("Cannot stat file");
       exit(1);
    }
    return st.st_mode;
}

int main(int argc, char **argv)
{    
    mode_t mode=getperm(argv[1]);
    int i=0;
    for(i=2; argv[i]!=NULL; i++)    
    {
       if(chmod(argv[i], mode)==-1)
          fprintf(stderr, "Permissions failed on %s:\n\t%s\n",
              argv[i], strerror(errno));
    }       
    return 0;
}
jim mcnamara
fuente