2010-08-10 151 views
19

我正在使用一個linux系統,需要在一組嵌套文件和目錄上試驗一些權限。我想知道是否沒有辦法保存文件和目錄的權限,而不必自己保存文件。是否可以創建腳本來保存和恢復權限?

換句話說,我想救燙髮,編輯一些文件,調整了一些權限,然後恢復權限返回到目錄結構,保持更改的文件到位。

這有道理嗎?

回答

4

HM。所以你需要 1)讀取文件的權限 2)存儲它們不知何故,與每個文件 3)讀取已存儲的權限,並設置回

不是一個完整的解決方案,但一些想法:

stat -c%a filename 
>644 

可能結合

find -exec 

來存儲這些信息,this so question有一些有趣的想法。基本上你創建一個臨時文件結構符合實際的文件,包含文件的權限

重置您遍歷你的臨時文件,讀取權限和chmod實際文件備份每個臨時文件。

+0

你完美地總結了它。現在要測試這個... – NinjaCat 2010-08-10 15:29:35

1

就可以獲取該文件的權限與

ls -l | awk '{print $1" "$NF}' 

將返回文件名及其權限的列表。 保存在某個地方,一旦你完成 - 恢復(chmod)每個文件的權限。

+3

[不要解析ls的輸出](http://mywiki.wooledge.org/ParsingLs) – Gilles 2010-08-10 15:29:02

+0

我想我可以把這個和@ second的結合起來想法... – NinjaCat 2010-08-10 15:29:54

35

最簡單的方法是使用ACL工具,即使你不實際使用的ACL。只需撥打getfacl -R . >saved-permissions備份目錄樹的權限,然後setfacl --restore=saved-permissions即可恢復它們。

否則,方法來備份的權限是find -printf。 (需要GNU發現,但這就是你在Linux上所擁有的。)

find -depth -printf '%m:%u:%g:%p\0' >saved-permissions 

你得到一個文件,其中包含由空字符分隔的記錄;每個記錄包含一個文件的數字權限,用戶名,組名和文件名。要恢復,請循環播放記錄並撥打chmodchown。該-depth選項find是如果你想使一些目錄不可寫(你必須先處理他們的內容)。

您可以用貢獻的Daniel Alder片段得出這個慶典片斷恢復的權限:

while IFS=: read -r -d '' mod user group file; do 
    chown -- "$user:$group" "$file" 
    chmod "$mod" "$file" 
done <saved-permissions 

您可以使用以下awk腳本打開find輸出到一些shell代碼來恢復權限。

find -depth -printf '%m:%u:%g:%p\0' | 
awk -v RS='\0' -F: ' 
BEGIN { 
    print "#!/bin/sh"; 
    print "set -e"; 
    q = "\047"; 
} 
{ 
    gsub(q, q q "\\" q); 
    f = $0; 
    sub(/^[^:]*:[^:]*:[^:]*:/, "", f); 
    print "chown --", q $2 ":" $3 q, q f q; 
    print "chmod", $1, q f q; 
}' > restore-permissions.sh 
+2

以前從未使用ACL工具,但我也喜歡這個... – NinjaCat 2010-08-10 15:30:28

+0

小修正getfacl命令應該是:getfacl -R。 > saved-permissions – mas 2011-11-14 13:26:41

+0

這是解決方案的第二部分:恢復文件:'while IFS =:read -r -d $''0'mod用戶組文件;做[-e「$ file」] ||繼續; chmod -c「$ mod」「$ file」; chown -Pc「$ user」「$ file」; chgrp -Pc「$ group」「$ file」; done 2015-09-29 20:25:00

3

還爲一個特殊的工具,稱爲metastore

metastore是要在一個文件樹中的文件/目錄/鏈接的元數據存儲到一個單獨的文件和工具稍後比較並將存儲的元數據應用於所述文件樹。我寫了這個工具作爲git的補充,它不存儲所有元數據,因此不適用於例如。存儲/等回購。如果您想創建文件樹的壓縮包並確保「所有內容」(例如xattrs,mtime,owner,group)與文件一起存儲,那麼metastore也會很有幫助。

它也可作爲Debian package

+0

Metastore的已停用Git回購已在https://github.com/przemoc/metastore上的GitHub上鏡像 – 2014-12-03 17:10:28

6

第一安裝ACL包:

sudo apt-get install acl 

遞歸商店權限和所有權到文件:

getfacl -R yourDirectory > permissions.acl 

還原(相對於當前路徑):

setfacl --restore=permissions.acl 
2

節省:find . -type f |xargs ls -la| awk '{print "chmod "$1" "$NF}'>./filesPermissions.sh

恢復:sh ./filesPermissions.sh

1

我發現從德米特羅大號非常酷的答案。但不幸的是,這是行不通的,因爲它產生這樣的條目:

chmod -rw-r--r-- ./.bashrc 

爲了避免它,我用下面的命令:

find . -type f | xargs stat -c "%a %n" | awk '{print "chmod "$1" "$2}' > ./filesPermissions.sh 

基本上,它確實是相同的,但產生八條目像:

chmod 644 ./.bashrc 

哪些工作。

+0

有人可能想引用/轉義文件名,否則帶空格的名稱將被錯誤地處理 – 2016-11-08 21:17:33

0

下面是使用單個文件輕鬆完成此操作的示例。不需要額外的工具,腳本,臨時文件等。如果需要,您可以擴展此方法以處理更多文件。

在此特定示例中,通過stat命令將權限保存在varibale中。然後,該文件暫時被剝奪任何限制性權限。接下來,它會完成一些工作(可能由於這些先前的限制而失敗)。最後,恢復原始權限。

file=$1 
saved_permissions=$(sudo stat -c %a $file) 
sudo chmod 777 $file 
# <DO SOMETHING HERE> 
sudo chmod $saved_permissions $file 
0
#!/bin/bash 

if [ $# -ne 1 ]; then 
     echo "Enter directory"; 
     exit 0; 
fi 
# dump acls 
cd $1 
>acl 
echo "#!/bin/bash">recovery_acl.sh 
echo "cd $1">>recovery_acl.sh 
f='./' 
# create acl file sorted by dir_level 
for i in `seq 0 15`;do 
    find . -mindepth $i -maxdepth $i -type d -exec getfacl {} +|grep -E '*UTS|file:'>>acl 
done 
sed -i 's/default\:user/\-dm\ u/g' acl 
sed -i 's/default\:group/\-dm\ g/g' acl 
sed -i 's/user\:/\-m\ u\:/g' acl 
sed -i 's/group\:/\-m\ g\:/g' acl 
sed -i 's/\#\ file\:\ /\.\//g' acl 
sed -i '/^#/d' acl 

while IFS='' read -r line ; do 
    # grep dir name 
    if echo "$line" | grep -q "$f" ; then 
    dir="$line" 
    continue 
    fi 
    echo setfacl $line '"'$dir'"'>>recovery_acl.sh 
    # grep non def acl (for files) 
    if echo "$line" | grep -q '\-m' ; then 
    echo setfacl $line '"'$dir'"'/*>>recovery_acl.sh 
    fi 
done < "acl" 
rm -f acl 
sed -i 's/134/\\/g' recovery_acl.sh 
sed -i 's/040/\ /g' recovery_acl.sh 

腳本執行後,將創造另一個 「recovery_acl.sh」。 替換您的域上的UTS。 像「沒有這樣的文件或目錄」的錯誤意味着目錄是空的。

0

我修改了Anton的命令以獲取附加字符串chown user:group/file_or_folder_path。現在你可以得到一個bash腳本,其中包含每個文件/文件夾的兩個字符串。

命令:輸出

find . -type f | xargs stat -c "%a %U:%G %n" | awk '{print "chown "$2" "$3"\nchmod "$1" "$3}' > ./filesPermissions.sh 

例子:

chown root:root /file_or_folder_path 
chmod 777 /file_or_folder_path 
0

我發現最好的方法(對我來說)做與蟒蛇!

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
import os 
import json 
import sys 
import re 
try: 
    import posix1e 
except ImportError: 
    print("No module named 'posix1e'") 
    print("You need do: apt install python3-pylibacl") 
    sys.exit() 

def dump_acl(dir): 
    acl_dict = {} 
    for root, dirs, files in os.walk(dir): 
     try: 
      path = root.split(os.sep) 
      root_acl = str(posix1e.ACL(file=root)) 
      root_def_acl = str(posix1e.ACL(filedef=root)) 
      #print(root_acl) 
      acl_dict[root] = root_acl 
      acl_dict["default_" + root] = root_def_acl 
      for file_name in files: 
       try: 
        if 'acl.json' in file_name: 
         continue 
        file_path = root + "/" + file_name 
        file_acl = str(posix1e.ACL(file=file_path)) 
        acl_dict[file_path] = file_acl 
        #print(file_path) 
       except Exception as e: 
        print(e) 
        print(root, '/' + file_name) 
        continue 
     except Exception as e: 
      print(e) 
      print(root, '/' + file_name) 
      continue 

    with open(dir + '/acl.json', 'bw') as f: 
     f.write(json.dumps(acl_dict, ensure_ascii=False).encode('utf8')) 
    return 


def recovery_acl(dir): 
    with open(dir + '/acl.json', 'r') as f: 
     acl_dict = json.load(f) 
    try: 
     for file_path, file_acl in acl_dict.items(): 
      if file_path.startswith('default_'): 
       file_path = file_path.replace('default_', '', 1) 
       posix1e.ACL(text = file_acl).applyto(file_path, posix1e.ACL_TYPE_DEFAULT) 
       continue 
      if 'acl.json' in file_path: 
       continue 
      file_acl = file_acl.replace('\n', ',', file_acl.count('\n') -1) 
      file_acl = file_acl.replace('\134', u'\ ' [:-1]) 
      file_acl = file_acl.replace('\040', u' ') 
      if 'effective' in file_acl: 
       file_acl = file_acl.replace('\t', '') 
       f_acl = re.sub('#effective:[r,w,x,-]{3}', '', file_acl) 
      posix1e.ACL(text = file_acl).applyto(file_path) 
    except Exception as e: 
     print(e, file_path, file_acl) 
    return 

def help_usage(): 
    print("Usage:") 
    print("For dump acl: ", sys.argv[0], "-d /path/to/dir") 
    print("For restore acl:", sys.argv[0], "-r /path/to/dir") 
    print("File with acls (acl.json) storing in the same dir") 
    sys.exit() 


if len(sys.argv) == 3 and os.path.isdir(sys.argv[2]): 
    if sys.argv[1] == '-d': 
     dump_acl(sys.argv[2]) 
    elif sys.argv[1] == '-r': 
     if os.path.exists(sys.argv[2] + '/acl.json'): 
      recovery_acl(sys.argv[2]) 
     else: 
      print("File not found:", sys.argv[2] + '/acl.json') 
else: 
    help_usage() 

備份ACL:dump_acl.py -d /路徑/到/目錄

恢復ACL:dump_acl.py -R /路徑/到/目錄

執行後,腳本創建ACL。 json in the same dir(witch backup/restore acls)