Standardmethode zum Kopieren der Berechtigungen einer Datei

6062
Alex

Ich versuche, eine Standard-POSIX-Methode zu finden, um die Berechtigungen einer Datei in eine andere Datei zu kopieren. Auf einem GNU-System ist das einfach:

[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 

Leider ist das Flag --reference zu chmod eine nicht standardmäßige Option. Das ist also für meine Zwecke. Ich würde es vorziehen, ein One-Liner zu sein, aber das ist nicht notwendig. Letztendlich muss es in POSIX-Syntax sein.

9

5 Antworten auf die Frage

9
Studer

Sie können den statBefehl verwenden, um die Dateiberechtigung zu erhalten:

  • Mac OS X (BSD) -Syntax:

    chmod `stat -f% A fileWithPerm` fileToSetPerm

  • Linux-Syntax (nicht sicher):

    chmod `stat -c% a fileWithPerm` fileToSetPerm

Das ` Symbol ist ein Backquote.

Ich denke nicht, dass "stat" von POSIX benötigt wird. Es ist oft nicht verfügbar. Dennis Williamson vor 13 Jahren 1
stat (Befehlszeile) ist nicht POSIX und nicht portierbar. Dennis ++ jim mcnamara vor 13 Jahren 0
6
Dennis Williamson

Eine Versuchung besteht darin, zu analysieren ls. Vermeiden Sie diese Versuchung .

Das Folgende scheint zu funktionieren, aber es ist voll von Kluge. Es stützt sich auf cpdie Berechtigungen der Zieldatei beibehalten wird . Für diese Demo darf die Datei "template" noch nicht vorhanden sein.

  • Kopieren Sie die Datei mit den gewünschten Berechtigungen in eine neue Datei
  • Kopieren Sie die Datei, die Sie ändern möchten, in die im vorherigen Schritt erstellte Datei
  • Entfernen Sie die Originaldatei, die Sie ändern möchten
  • Benennen Sie die Zwischendatei in den Namen der zu ändernden Datei um

Demo:

$ 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 
Das ist ein interessanter Ansatz. Ich werde das testen und sehen, wie gut es mit verschiedenen Servern funktioniert. Es scheint mir, als würde es den Trick tun. Alex vor 13 Jahren 0
@Alex: Stellen Sie sicher, dass Sie die Datei auch mit dem Dateibesitz testen, wenn dies ein Problem ist. Dennis Williamson vor 13 Jahren 0
Der erste cp-Befehl, "cp has template", sollte "cp -p" verwenden, um die Modus- und Besitzattribute zu erhalten. mernst vor 9 Jahren 0
@mernst: Das ist nur für das erste `cp` notwendig, wenn sich der Besitzer / die Gruppe der Datei (zB" user ") von der unterscheidet, die das Kopieren vornimmt (zB root). Dennis Williamson vor 9 Jahren 0
@Dennis Willamson: OK, aber das ist eine Möglichkeit und ich sehe keinen Nachteil darin, `cp -p` dort zu verwenden. mernst vor 9 Jahren 0
0
Janne Pikkarainen

Die ACL-Dienstprogramme getfacl und setfacl können für diesen Zweck verwendet werden, aber ich weiß nicht, ob diese POSIX-Kompatibilität ausreichend ist. Funktioniert zumindest in FreeBSD 8.0 und Linux, andererseits müssen die ACL-Dienstprogramme jedoch installiert werden.

Von der Manpage:

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

Ich denke, getfacl und setfacl können neben ACLs auch Standard-Dateiberechtigungen betreiben.

ACLs und solche, die von POSIX definiert werden, sind implementierungsspezifisch und daher nicht für die Konformität erforderlich. Dennis Williamson vor 13 Jahren 0
0
user31894

cp -p behält die Dateiberechtigungen bei.

Deshalb funktioniert die Technik in meiner Antwort (von * nicht * mit '-p') für das, was das OP wünscht, das die Berechtigungen für eine * andere * Datei dupliziert, nicht für ein * Duplikat * der Datei. Dennis Williamson vor 13 Jahren 1
0
jim mcnamara

Ein tragbarer, unkomplizierter Weg ist kein Standard-Dienstprogramm. Sie müssen stat () für die Vorlagendatei und dann chmod () für die Zieldatei (en) aufrufen. Dies bedeutet, dass Sie eine Sprache wie C oder eine andere weit verbreitete Sprache wie Perl verwenden.

Die Dateizugriffsberechtigungen werden in dem Mitglied von struct stat st_mode durch die Bits 0007777 angegeben. Die Lösung von Dennis ist korrekt, wenn auch die E / A-Werte etwas anstrengend sind. Bei wirklich großen Dateien kann dies jedoch fehlschlagen:

cp has template 

Betrachten Sie dieses nicht fertige Beispiel:

#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; }