Ya sistem dizinlerinde yanlışlıkla “chmod -R” komutunu çalıştırsam (/, / etc,…)


56

Yanlışlıkla koştum

sudo chmod 755 -R /

onun yerine

sudo chmod 755 -R ./

Birkaç saniye sonra durdurdum ama şimdi bazı sorunlar var.

sudo: must be setuid root

İzinleri nasıl geri alabilirim?


18
sevgili ah ... sudoaraçlar, sahip olduğu iki kez düşünmek ne yapacağını!
antivirtel

2
En kolay yeniden yüklemektir. LiveCD / USB'yi yerleştirin ve diskinizi bölümlemenizi istediği ekrana size bir seçenek sunmalıdır Upgrade from Ubuntu 11.04 to Ubuntu 11.04. Bu seçeneği kabul edin; Ubuntu'yu en acısız şekilde sizin için etkili bir şekilde yeniden kurar.
user4124

13
Az önce bir ders öğrendin. /Dizini hedef olarak belirtmek için dizin adının sonuna yazmanız gerekmez . Bu kötü bir alışkanlık , yapma, asla ! Kendi .başına geçerli bir dizin adıdır, eklemeye gerek yoktur /. Eğer herkes bu kuralı uygulasaydı, o zaman çok yanlış yazılmış sudoişlemlerin kök dizini üzerinde bir etkisi olmazdı, bu yüzden sistemlerine zarar vermemeliydi. Yapma!
ulidtko

3
@ fl00r, evet. Bu, "geçerli" dizin anlamına gelen bir dizin adıdır. cd .örneğin hiçbir şey yapmaz. ls .aynıdır ls. Ayrıca, .."ebeveyni" anlamına gelen bir dizin adıdır .ve muhtemelen zaten biliyorsunuzdur.
ulidtko

2
@ ulidtko: /Sonunda kullanmamanın bir istisnası var . Yalnızca dizinler için yol adı genişletme yapmak istiyorsanız. Geçerli dizindeki dizinlerin listelenmesi örneği:echo */
pabouk

Yanıtlar:


56

Kısacası: yapamazsınız, sisteminizi yeniden yükleyin.

Yani, Posix izinleri yoğun olarak kullanılıyor ve güveniliyor; Dosya sisteminde yanlış izinlerin işletim sistemini (SUID bayrakları) kırabileceği veya daha da kötüsü, tamamıyla /etc/ssh/ssh_host_rsa_keyçalışıyor gibi göründüğü durumlarda güvenlik açısından ( ) açıkça ortaya çıkacağı çok sayıda yer var .

Bu nedenle, böyle bir iyileşme düzgün yapmak zordur. Bir şeyi özlüyorum - ve sen batırdın. Sen zatensudo chmod komutunu berbat ettin ( senden ziyade senin arkadaşınsa , Linux dersini de öğrenebilir) - ve bu çok basit bir komut. Doğru bir şekilde toparlanması, daha fazla komut ve daha fazla dikkat gerektirir. Birinin senaryosunu kullansanız bile.

Bana güven, tekrar yükle. Bu güvenli bir bahis ve sizi beladan uzak tutmak için garantilidir.


Sonunda, burada ilgili bazı ipuçları.

İlk: yeniden yüklemelerine eğer daha az acı verir kurulum /homeayrı bir bölüme dahaki sefere. Aslında bir esinti olacaklar.

İkincisi: yapıyor düşünün deli Linux bilimi bir de sanal makine VirtualBox gibi, ve anlık yapmak.

Üçüncüsü: chmod -R .çalışır. Bir nokta kendi başına .geçerli bir dizin adıdır. Bu eğik çizgiyi eklemeye gerek yok. Noktayı tamamen atlamak için feci bir riskten kaçınabilirdiniz;
sadece chmod: missing operand after ‘755’VS yıkık bir sistem.


1
Ahhh :) çok üzücü.
fl00r

14
Iyi olabilir başka bir sistemden her dosya için tüm izinleri almak, ancak yaparak bu muhtemelen sadece yeniden kolay ve daha güvenli olurdu bu kadar iştir.
Oli

2
Ve üzülme! Büyük bir güçle büyük sorumluluk geliyor
ulidtko

Evet, dizüstü bilgisayarımı bununla daha yeni mahvettim ... İnanılmaz linux tabanlı bir makineyi kolayca nasıl imha edersiniz.
amanuel2

@ amanuel2 büyük güce sahip büyük sorumluluk getirir. Ne yazdığına dikkat et; sudoiki kez kontrol etmeniz gerektiği anlamına gelir.
ulidtko

26

Birkaç yıldan beri birkaç Ruby yazarı rsyncizinleri ve mülkiyeti için yazdım ve kullanıyorum . Script get-filesystem-acl, tüm dosyaları tekrar tekrar gezdirerek toplar ve hepsini dosyaya koyar .acl. Script tüm 'leri ve ' leri .acl-restoreokuyacak .aclve uygulayacaktır .chownchmod

Kaçabilirsiniz get-filesystem-aclbenzer Ubuntu yüklemesinde ve sonra üzerinden kopyalama .aclkoymak, sizin chmod hasarlı kutusuna dosyanın .aclve .acl-restore/ içinde ve çalıştırın .acl-restore.

Kökün olması gerekecek, bu yüzden sudoMarco Ceppi'nin önerdiği gibi düzeltin .

.aclUbuntu'm için dosyayı oluşturabilir ve verebilirim .

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

Ubuntu 11.04. Ama şimdiden tekrar yükledim. Teşekkürler!
fl00r

betiğiniz owner_idtanımsız olduğu için başarısız oldu
Eliran Malka

8
tür bir overkill ... bulmak oldukça güzel yapar:find SOME_DIR -depth -printf 'chmod %m %p\n' > saved_permission
reflog

12

Uzun zaman: yapabilirsin. Dosya sistemini Canlı CD'den bağlamanız ve izinleri uygun yerlerde geri almanız gerekir. Sudo'yu geri almak için en azından sudo chmod u+s /usr/bin/sudoLiveCD oturumunda çalıştırmak isteyeceksiniz - bu setuid root'u düzeltmelidir.

Bununla birlikte, sistemi kolayca yeniden kurmak daha kolay olacaktır.


4

Tüm paketleri yeniden kurmaya çalışırdım apt-get install --reinstall, muhtemelen dpkg --get-selections | grep installbir listesini almak için çıktılarını kullanıyordum .


Bu kötü bir fikir değildir, ancak otomatik olarak yüklenen şeyleri dışlamanız gerekir veya kalıcı olarak bu paketlerle sonuçlanırsınız (bağımlı paketleri çıkarsanız bile) ... Ama sonra yeniden kurulmazlardı. Çetin ceviz. Belki de önce otomatik paketlerin bir listesini almak, sonra her paketi yeniden yüklemek, sonra otomatik olarak yeniden işaretlemek için otomobil listesine göz atın.
Oli

@Oli - çalıştırılarak çözülemeyen (bazıları) olmaz sudo apt-get autoremovemı?
Wilf,

@Wilf No - autoremoveyalnızca el ile yüklemediğiniz paketleri kaldırır.
Dmitry Grigoryev

3

Tamam, bunu test etmedim (bu nedenle kendi sorumluluğunuzda kullanın), ancak yine de işe yarayabilir. Bunu yapma şansım olduğu zaman bunu sanal bir makinede test edeceğim:

İlk önce, hala çalışan bir sistemde, listedeki tüm dosya izinlerini almak için aşağıdakileri yaptım, /home/dizini atladım :

sudo find / -not -path /home -printf "%m:%p\0" > /tmp/fileper.log

Bu, sistemdeki her dosya veya dizin için izinleri ve dosya adını yazıp ardından bir \0karakter izler (bu, daha sonra yeni satırları içerenler gibi garip dosya adları ile ilgilenmek için gereklidir).

Ardından, dosya izinlerinin ihlal edildiği bir sistemde:

while IFS=: read -r -d '' perm file; do  
    chmod "$perm" "$file"
done < /tmp/fileper.log 

Bu fileper.log, izinleri $permve dosya adını aşağıdaki şekilde kaydederek her satırını okuyacak $fileve ardından dosya (veya müdürün) izinlerini listede listelenenlere ayarlayacaktır.fileper.log


Burada dikkat edilmesi gereken birkaç şey:

  • Dosyaya çıktı verirken: /tmp/fileper.logözel ayarları ve proc'ları vb. Listeliyor olabilirsiniz.
  • önyükleme yapamayabilir veya komutları çalıştıramayabilirsiniz.

Önereceğim şey, diskinizde sahip olduğunuz Linux sürümüyle bir LiveCD başlatmak, komutu çalıştırmak, yerel diskin monte edildiği yolu değiştirmek ve ikinci komutu çalıştırmak!


Ben Bir Ubuntu CD / USB'den boot zaman, ben her şeyi değiştirecektir, yani diski biçimlendirmek için değil seçebilirsiniz test ettik /dizine, AMA atlamak /home/dizin. Yani, kullanıcılarınız hala uygulamalar / DATA (Müzik, Video, Belgeler) konfigürasyonuna sahip olacaklar. Ve sistem dosyalarını değiştirerek, chmodorada uygun numaraya ayarlanır.


1
Neden chmod $(echo $LINE)sadece chmod $LINE? Ayrıca, sadece kullanabilirsiniz findolmadan stat: find … -printf "%#m %p\n". Daha da iyisi, komutun tamamını oluşturabilirsiniz:, find … -printf "chmod %#m %p\n"ardından dosyayı komut dosyası olarak yürütün.
muru

Bulma çizgisi olduğu gibi çalışmaz, olması gerektiği gibi, michael@NEXUS-TWO:~$ sudo find / -name '*' -exec stat -c "%a %n" {} \; >> /tmp/fileper.logancak daha sonra da çalışır /procve listenizde istemediğiniz diğer yerler.
Videonauth,

@muru bunu gecenin ortasında yazdı. ... kodunu düzenlemek Will
blade19899

Kullanıcı girişi üzerinde de durulacaktır, test etme olanağı değil
blade19899

3

(Bir cevapta yorum yapmamam gerektiğini biliyorum, ancak yorum yapmak için yeterli itibar göstermemeliyim.)

blade19899'ın cevabı, sembolik bağlantılar dışında benim için çalıştı. Örneğin 755 / bin / bash'a uygulandı, ancak daha sonra 777 symlink / bin / rbash'a, 777-ing / bin / bash'a uygulandı.

Ben zaten fileper.log dosyasına sahip olduğum için hedef-bitiş komutunu değiştirdim:

while IFS=: read -r -d '' perm file; do  
    if [[ ! -L "$file" ]]; then    
        chmod "$perm" "$file"
    fi
done < /tmp/fileper.log 

İzinlerin yedeğini alıyorsanız, neden yalnızca tam bir yedekleme yapıp gerektiğinde geri yüklemiyorsunuz? Bu sadece herhangi bir komutun yanlışlıkla çalıştırılması durumunda sizi kurtaracaktır chmod.
Dmitry Grigoryev

2

İle izinleri geri yüklemeyi deneyebilirsiniz apt-get.

Bu komutları sudo ile çalıştıramazsanız, kurtarma moduna önyükleme yapmanız ve kök olarak çalıştırmanız gerekebilir.

Kurtarma moduna geçmek için https://wiki.ubuntu.com/RecoveryMode adresini ziyaret edin .

Gönderen http://hyperlogos.org/page/Restoring-Permissions-Debian-System

Not: Bu başlangıçta Ubuntu Forumlarına gönderildi, ancak orijinal yazıyı bulamıyorum.

Sırasıyla, deneyin

sudo apt-get --reinstall install `dpkg --get-selections | grep install | grep -v deinstall | cut -f1`

Bu başarısız olursa:

sudo apt-get --reinstall install `dpkg --get-selections | grep install | grep -v deinstall | cut -f1 | egrep -v '(package1|package2)'`

Ve son olarak, son çare olarak,

sudo dpkg --get-selections | grep install | grep -v deinstall | cut -f1 | xargs apt-get --reinstall -y --force-yes install

Apt-get kullanarak

İşte DOĞRULUK İÇİN DEĞİŞTİRİLEN ve yeniden biçimlendirilen ilgili snip:

sudo apt-get --reinstall install `dpkg --get-selections | grep install | grep -v deinstall | cut -f1`

Diyelim ki, yeniden yüklenemeyen bazı paketler hakkında mesajlar alıyorsunuz ve komut başarısız. Söz konusu paketleri atlayarak düzeltmenin bir yolu:

sudo apt-get --reinstall install `dpkg --get-selections | grep install | grep -v deinstall | cut -f1 | egrep -v '(package1|package2)'`

Ve nihayet, eğer bir şekilde yukarıdaki komutun argüman listenizin çok uzun olduğunu söyleyemediği bir şey kurmanız gerekiyorsa, apt-get komutunu istediğinizden daha fazla çalıştıracak olan düzeltme:

sudo dpkg --get-selections | grep install | grep -v deinstall | cut -f1 | xargs apt-get --reinstall -y --force-yes install

Not -yve --force-yesduracaktır seçenekleri, apt-gettekrar tekrar istenmesini. Bunlar her zaman eğlenceli seçeneklerdir, ne yaptığınızı bildiğinizden eminseniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.