Tôi đã viết và đã sử dụng vài năm một vài tập lệnh Ruby để cấp rsync
quyền và quyền sở hữu. Script get-filesystem-acl
thu thập tất cả thông tin bằng cách duyệt qua tất cả các tệp và đặt tất cả vào tệp .acl
. Script .acl-restore
sẽ đọc .acl
và áp dụng tất cả các chown
và chmod
.
Bạn có thể chạy get-filesystem-acl
trên bản cài đặt Ubuntu tương tự và sau đó sao chép .acl
tệp vào hộp bị hỏng chmod của bạn, đặt .acl
và .acl-restore
vào /, và chạy .acl-restore
.
Bạn sẽ cần phải có root để sửa lỗi sudo
như Marco Ceppi đề xuất.
Tôi có thể tạo và cung cấp cho bạn .acl
tệp cho Ubuntu của tôi.
get-filesystem-acl
#!/usr/bin/ruby
RM = "/bin/rm"
SORT = "/usr/bin/sort"
TMP = "/tmp/get_acl_#{Time.now.to_i}_#{rand * 899 + 100}"
require 'find'
IGNORE = [".git"]
def numeric2human(m)
return sprintf("%c%c%c%c%c%c%c%c%c",
(m & 0400 == 0 ? ?- : ?r),
(m & 0200 == 0 ? ?- : ?w),
(m & 0100 == 0 ? (m & 04000 == 0 ? ?- : ?S) :
(m & 04000 == 0 ? ?x : ?s)),
(m & 0040 == 0 ? ?- : ?r),
(m & 0020 == 0 ? ?- : ?w),
(m & 0010 == 0 ? (m & 02000 == 0 ? ?- : ?S) :
(m & 02000 == 0 ? ?x : ?s)),
(m & 0004 == 0 ? ?- : ?r),
(m & 0002 == 0 ? ?- : ?w),
(m & 0001 == 0 ? (m & 01000 == 0 ? ?- : ?T) :
(m & 01000 == 0 ? ?x : ?t)))
end
File.open(TMP, "w") do |acl_file|
# TODO: Instead of the current dir, find the .git dir, which could be
# the same or outside of the current dir
Find.find(".") do |path|
next if IGNORE.collect {|ig| !!(path[2..-1] =~ /\A#{ig}/)}.include? true
next if File.symlink?(path)
stat = File.lstat(path)
group_id = stat.gid
rules = "#{type}#{numeric2human(stat.mode)}"
acl_file.puts "#{path} #{rules} #{owner_id} #{group_id}"
end
end
`#{SORT} #{TMP} > .acl`
`#{RM} #{TMP}`
.acl-restore
#!/usr/bin/ruby
# This script will only work with .acl_ids
# Restore from...
FROM = ".acl"
MKDIR = "/bin/mkdir"
CHMOD = "/bin/chmod"
CHOWN = "/bin/chown"
known_content_missing = false
def numeric2human(m)
return sprintf("%c%c%c%c%c%c%c%c%c",
(m & 0400 == 0 ? ?- : ?r),
(m & 0200 == 0 ? ?- : ?w),
(m & 0100 == 0 ? (m & 04000 == 0 ? ?- : ?S) :
(m & 04000 == 0 ? ?x : ?s)),
(m & 0040 == 0 ? ?- : ?r),
(m & 0020 == 0 ? ?- : ?w),
(m & 0010 == 0 ? (m & 02000 == 0 ? ?- : ?S) :
(m & 02000 == 0 ? ?x : ?s)),
(m & 0004 == 0 ? ?- : ?r),
(m & 0002 == 0 ? ?- : ?w),
(m & 0001 == 0 ? (m & 01000 == 0 ? ?- : ?T) :
(m & 01000 == 0 ? ?x : ?t)))
end
def human2chmod(mode)
raise unless mode =~ /([r-][w-][xtsTS-])([r-][w-][xtsTS-])([r-][w-][xtsTS-])/
triple = [$1, $2, $3]
u,g,o = triple.collect do |i|
i.sub('s', 'sx').sub('t', 'tx').downcase.gsub('-', '')
end
return "u=#{u},g=#{g},o=#{o}"
end
File.open(FROM).each do |acl|
raise unless acl =~ /\A(([^ ]*? )+)([^ ]+) ([^ ]+) ([^ ]+)\Z/
path, rules, owner_id, group_id = $1, $3, $4, $5
path = path.strip
owner_id = owner_id.to_i
group_id = group_id.to_i
if !File.exists?(path) and !File.symlink?(path)
if rules =~ /\Ad/
STDERR.puts "Restoring a missing directory: #{path}"
STDERR.puts "Probably it was an empty directory. Git goes not track them."
`#{MKDIR} -p '#{path}'` # Creating the any parents
else
known_content_missing = true
STDERR.puts "ERROR: ACL is listed but the file is missing: #{path}"
next
end
end
s = File.lstat(path)
t = s.ftype[0..0].sub('f', '-') # Single character for the file type
# But a "-" istead of "f"
# Actual, but not neccesarely Desired
actual_rules = "#{t}#{numeric2human(s.mode)}"
actual_owner_id = s.uid
actual_group_id = s.gid
unless [actual_rules, actual_owner_id, actual_group_id] ==
[rules, owner_id, group_id]
chmod_argument = human2chmod(rules)
# Debug
#p chmod_argument
#p s.mode
## Verbose
puts path
puts "Wrong: #{[actual_rules, actual_owner_id, actual_group_id].inspect}"
puts "Fixed: #{[rules, owner_id, group_id].inspect}"
`#{CHMOD} #{chmod_argument} '#{path}'`
#puts
end
end
if known_content_missing
STDERR.puts "-" * 80
STDERR.puts "Some files that are listed in #{FROM.inspect} are missing in " +
"the current directory."
STDERR.puts
STDERR.puts "Is #{FROM.inspect} outdated?"
STDERR.puts "(Try retrograding the current directory to an earlier version)"
STDERR.puts
STDERR.puts "Or is the current directory incomplete?"
STDERR.puts "(Try to recover the current directory)"
STDERR.puts "-" * 80
end
sudo
có nghĩa là, bạn đã nghĩ gấp đôi những gì bạn sẽ làm!