Was ist, wenn ich versehentlich den Befehl "chmod -R" in Systemverzeichnissen (/, / etc,…) ausführe?

56

Ich bin aus Versehen gerannt

sudo chmod 755 -R /

Anstatt von

sudo chmod 755 -R ./

Ich habe es nach ein paar Sekunden gestoppt, aber jetzt gibt es einige Probleme wie

sudo: must be setuid root

Wie kann ich Berechtigungen zurücksetzen?

fl00r
quelle
18
oh je ... sudobedeutet, dass du dir zweimal überlegt hast, was du tun wirst!
Antivirtel
2
Am einfachsten ist die Neuinstallation. Legen Sie die LiveCD / USB ein und geben Sie auf dem Bildschirm, auf dem Sie aufgefordert werden, Ihre Festplatte zu partitionieren, die Option dazu ein Upgrade from Ubuntu 11.04 to Ubuntu 11.04. Wenn Sie diese Option akzeptieren, wird Ubuntu auf die schmerzloseste Weise für Sie neu installiert.
user4124
13
Sie haben gerade eine Lektion gelernt. Sie müssen nicht /am Ende des Verzeichnisnamens schreiben , um das Verzeichnis als Ziel anzugeben. Es ist eine schlechte Angewohnheit , tu es nicht, niemals ! Der .an sich gültige Verzeichnisname muss nicht angehängt werden /. Wenn alle diese Regel befolgen sudowürden, hätten sehr viele falsch geschriebene Operationen keine Auswirkungen auf das Stammverzeichnis, sodass ihren Systemen kein Schaden zugefügt worden wäre. Tu es nicht!
ulidtko
3
@ fl00r, ja. Es ist ein Verzeichnisname, der dieses oder "aktuelles" Verzeichnis bedeutet. cd .tut zum Beispiel nichts. ls .ist das gleiche wie ls. Außerdem ist das ..ein Verzeichnisname, der "das übergeordnete Element von ." bedeutet, und Sie wussten es wahrscheinlich bereits.
ulidtko
2
@ulidtko: Es gibt eine Ausnahme, die /am Ende nicht verwendet wird . Wenn Sie die Pfadnamenerweiterung nur für Verzeichnisse ausführen möchten. Beispiel für die Auflistung von Verzeichnissen im aktuellen Verzeichnis:echo */
pabouk

Antworten:

57

Kurz gesagt: Sie können Ihr System nicht neu installieren.

Ich meine, Posix-Berechtigungen werden in hohem Maße verwendet und genutzt. Es gibt eine Vielzahl von Stellen im Dateisystem, an denen falsche Berechtigungen das Betriebssystem beschädigen (SUID-Flags) oder, noch schlimmer, es in Bezug auf die Sicherheit offen legen ( /etc/ssh/ssh_host_rsa_key), während es anscheinend einwandfrei funktioniert.

Daher ist eine solche Wiederherstellung nur schwer richtig durchzuführen. Verpassen Sie eine Sache - und Sie vermasseln es. Sie haben Ihren Befehl bereits verkorkst sudo chmod(wenn das eher Ihre Freundin als Sie ist, könnte sie auch eine Linux-Lektion lernen) - und das ist ein sehr einfacher Befehl. Eine ordnungsgemäße Wiederherstellung würde viel mehr Befehle und viel mehr Wachsamkeit erfordern. Auch wenn Sie jemandes Skript verwenden.

Also vertrau mir, einfach neu installieren. Es ist eine sichere Wette und garantiert, dass Sie keine Probleme haben.


Abschließend noch einige hier relevante Tipps.

Erstens: Neuinstallationen sind weniger schmerzhaft, wenn Sie sie das/home nächste Mal auf einer separaten Partition einrichten. Eigentlich werden sie ein Kinderspiel sein.

Zweitens: Denken Sie darüber nach, verrückte Linux-Wissenschaft in einer virtuellen Maschine wie der VirtualBox zu betreiben und machen Sie Ihre Snapshots.

Drittens: chmod -R .funktioniert. Ein Punkt für sich .ist ein gültiger Verzeichnisname. Dieser Schrägstrich muss nicht wirklich angehängt werden. Sie hätten das katastrophale Risiko vermeiden können, den Punkt komplett zu überspringen.
bloß chmod: missing operand after ‘755’VS ein ruiniertes System.

ulidtko
quelle
1
Ahhh :) so traurig.
Freitag,
14
Nun, Sie könnten alle Berechtigungen für jede Datei von einem anderen System erhalten, aber dies ist so viel Arbeit, dass es wahrscheinlich einfacher und sicherer wäre, sie einfach neu zu installieren.
Oli
2
Und sei nicht traurig! Mit großer Macht geht große Verantwortung
einher
Ja, ich habe gerade meinen Laptop damit zerstört ... Erstaunlich, wie leicht man einen Linux-basierten Rechner zerstören kann.
amanuel2
@ amanuel2 mit großer kraft kommt große verantwortung. Beobachten Sie, was Sie tippen; sudobedeutet, dass Sie zweimal überprüfen müssen.
ulidtko
26

Ich habe einige Ruby-Skripte geschrieben und benutze sie seit einigen Jahren, um rsyncBerechtigungen und Eigentumsrechte zu erhalten. Das Skript get-filesystem-aclsammelt alle Informationen, indem es alle Dateien rekursiv durchläuft und in die Datei einfügt .acl. Das Skript .acl-restoreliest .aclund wendet alle chownund an chmod.

Sie können get-filesystem-acleine ähnliche Ubuntu-Installation ausführen und dann die .aclDatei auf Ihre mit chmod beschädigte Box kopieren, sie einfügen .aclund .acl-restore/ eingeben und ausführen .acl-restore.

Du musst root haben, also repariere es sudowie von Marco Ceppi vorgeschlagen.

Ich kann dir die .aclDatei für mein Ubuntu generieren und geben .

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
Aleksandr Levchuk
quelle
Ubuntu 11.04. Aber ich habe es bereits neu installiert. Vielen Dank!
Freitag,
Ihr Skript schlägt fehl, wie nicht owner_iddefiniert
Eliran Malka
8
irgendwie ein Overkill ... finde das ganz nett:find SOME_DIR -depth -printf 'chmod %m %p\n' > saved_permission
Reflog
12

Auf lange Sicht: Sie können. Sie müssen das Dateisystem von einer Live-CD mounten und die Berechtigungen an den entsprechenden Stellen zurücksetzen. Zumindest, um sudo wiederzuerlangen, sollten Sie sudo chmod u+s /usr/bin/sudoin der LiveCD-Sitzung ausgeführt werden. Dies behebt den Fehler, der als root festgelegt werden muss.

Es wäre jedoch wahrscheinlich einfacher, das System einfach neu zu installieren.

Marco Ceppi
quelle
4

Ich würde versuchen, alle Pakete mit neu zu installieren apt-get install --reinstall, möglicherweise mithilfe der Ausgabe von dpkg --get-selections | grep install, um eine Liste von ihnen zu erhalten.

Adam Byrtek
quelle
Dies ist keine schlechte Idee, aber Sie müssen Dinge ausschließen, die automatisch installiert werden, oder Sie würden dauerhaft mit diesen Paketen enden (selbst wenn Sie die abhängigen Pakete entfernt hätten) ... Aber dann würden sie nicht erneut installiert. Schwierig. Vielleicht zuerst eine Liste der automatischen Pakete abrufen, dann jedes Paket neu installieren , dann die Liste der Autos durchgehen und sie erneut als automatisch markieren.
Oli
@Oli - würden (einige von) das nicht durch Laufen lösen sudo apt-get autoremove?
Wilf
@Wilf Nein - Entfernt autoremovenur Pakete, die Sie nicht manuell installiert haben.
Dmitry Grigoryev
Es gibt apt-mark auto $pkg/ mit apt-mark manual $pkgdenen Sie den Status von "manuell installiert / automatisch installiert" pro Paket ändern können.
ulidtko vor
3

Okay, ich habe das nicht getestet (also benutze es auf dein eigenes Risiko), aber es könnte trotzdem funktionieren. Ich werde dies in einer virtuellen Maschine testen, wenn ich die Möglichkeit habe:

Zunächst habe ich in einem noch funktionierenden System Folgendes getan, um alle Dateiberechtigungen in einer Liste abzurufen, wobei das /home/Verzeichnis übersprungen wurde :

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

Dadurch werden die Berechtigungen und der Dateiname für jede Datei oder jedes Verzeichnis auf dem System gedruckt, gefolgt von einem \0Zeichen (dies wird später benötigt, um seltsame Dateinamen wie z. B. solche mit Zeilenumbrüchen zu behandeln).

Dann auf einem System, auf dem die Dateiberechtigungen gefährdet wurden:

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

Dies liest jede Zeile von fileper.log, speichert die Berechtigungen als $permund den Dateinamen als $fileund setzt dann die Berechtigungen der Datei (oder des Verzeichnisses) auf die in der aufgelisteten Wertefileper.log


Ein paar Dinge, die Sie hier beachten sollten:

  • Während der Ausgabe in die Datei: /tmp/fileper.logwerden möglicherweise benutzerdefinierte Einstellungen, die Verarbeitung usw. aufgelistet.
  • Sie sind möglicherweise nicht in der Lage, Befehle zu starten oder auszuführen.

Ich würde vorschlagen, eine LiveCD mit der Linux-Version zu starten, die Sie auf Ihrer Festplatte haben, den Befehl auszuführen, den Pfad dahin zu ändern, wo Sie die lokale Festplatte gemountet haben, und den zweiten Befehl auszuführen!


Ich habe getestet, dass ich beim Booten von einer Ubuntu-CD / USB entscheiden kann, die Festplatte nicht zu formatieren, was bedeutet, dass alles im /Verzeichnis ersetzt wird, ABER das /home/Verzeichnis überspringen . Das heißt, Ihre Benutzer haben die Konfiguration von Apps / DATA (Musik, Video, Dokumente) noch intakt. Und durch Ersetzen der Systemdateien wird die chmodrichtige Anzahl eingestellt.

blade19899
quelle
1
Warum chmod $(echo $LINE)statt nur chmod $LINE? Außerdem können Sie verwenden , nur findohne stat: find … -printf "%#m %p\n". Besser noch, Sie können den gesamten Befehl erstellen: find … -printf "chmod %#m %p\n"und dann die Datei als Skript ausführen.
muru
Die Find-Zeile funktioniert nicht wie sie ist, es sollte michael@NEXUS-TWO:~$ sudo find / -name '*' -exec stat -c "%a %n" {} \; >> /tmp/fileper.logaber auch so sein, dass sie überläuft /procund an einigen anderen Stellen, die Sie möglicherweise nicht in Ihrer Liste haben möchten.
Videonauth
@muru schrieb dies mitten in der Nacht. Wird den Code bearbeiten ...
Blade19899
Nicht in der Lage zu testen, wird auf Benutzereingaben angewiesen
Blade19899
2

(Ich weiß, ich sollte in einer Antwort keinen Kommentar abgeben, aber nicht genug Ruf, um einen Kommentar abzugeben.)

Die Antwort von blade19899 hat mit Ausnahme von Symlinks für mich funktioniert. ZB 755 auf / bin / bash angewendet, aber dann 777 auf symlink / bin / rbash angewendet, effektiv 777-ing / bin / bash.

Da ich bereits die Datei fileper.log hatte, habe ich den Befehl destination-end geändert:

while IFS=: read -r -d '' perm file; do  
    if [[ ! -L "$file" ]]; then    
        chmod "$perm" "$file"
    fi
done < /tmp/fileper.log 
Marjan
quelle
Wenn Sie eine Berechtigungssicherung haben, warum nicht einfach eine vollständige Sicherung erstellen und diese bei Bedarf wiederherstellen? Das erspart Ihnen im Falle eines versehentlich ausgeführten Befehls nicht nur chmod.
Dmitry Grigoryev
> ... effectively 777-ing /bin/bash- nein; so geht es nicht. Wollen Sie damit sagen, dass ich als Nicht-Root-Benutzer durch /usr/bin/aptmein eigenes Ding ersetzen kann, indem ich einfach über einen 777-Symlink darauf schreibe? :) Übe kritisches Denken; Symlinks können und funktionieren nicht so. 777 Berechtigungen für Symlinks sind allgemein und normal.
ulidtko vor
2

Sie können versuchen, Berechtigungen mit wiederherzustellen apt-get.

Wenn Sie diese Befehle nicht mit sudo ausführen können, müssen Sie möglicherweise in den Wiederherstellungsmodus booten und sie als root ausführen.

Informationen zum Booten in den Wiederherstellungsmodus finden Sie unter https://wiki.ubuntu.com/RecoveryMode .

Von http://hyperlogos.org/page/Restoring-Permissions-Debian-System

Hinweis: Dies wurde ursprünglich in den Ubuntu-Foren gepostet, aber ich kann den ursprünglichen Beitrag nicht finden.

Versuchen Sie, in der Reihenfolge,

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

Wenn das fehlschlägt:

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

Und schließlich als letztes Mittel,

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

Mit apt-get

Hier ist der relevante Ausschnitt, BEARBEITET FÜR RICHTIGKEIT und neu formatiert:

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

Angenommen, Sie erhalten Nachrichten zu einigen Paketen, die nicht erneut installiert werden können, und der Befehl schlägt fehl. Hier ist eine Möglichkeit, das Problem durch Überspringen der betreffenden Pakete zu beheben:

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

Und schließlich, wenn Sie irgendwie so viele Dinge installiert haben sollten, dass der obige Befehl nicht sagt, dass Ihre Argumentliste zu lang ist, ist hier der Fix, der apt-get viel öfter ausführt, als Sie vielleicht möchten:

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

Beachten Sie die Optionen -yund --force-yes, die apt-getSie nicht mehr immer wieder dazu auffordern. Dies sind immer lustige Optionen, wenn Sie sicher sind, dass Sie wissen, was Sie tun.

Panther
quelle