अगर मैं गलती से सिस्टम निर्देशिका (/, / etc,…) पर कमांड "chmod -R" चलाऊं तो ...


56

मैं अकस्मात भागा

sudo chmod 755 -R /

के बजाय

sudo chmod 755 -R ./

मैंने कुछ सेकंड के बाद इसे रोक दिया, लेकिन अब कुछ समस्याएं हैं जैसे कि

sudo: must be setuid root

मैं अनुमति वापस कैसे कर सकता हूं?


18
हे प्रिय ... का sudoमतलब है, कि आपने दो बार सोचा है कि आप क्या करेंगे!
एंटीवायरल

2
पुनः स्थापित करना सबसे आसान है। LiveCD / USB रखो, और स्क्रीन पर जहां यह आपको अपनी डिस्क को विभाजित करने के लिए कहता है, यह आपको विकल्प देना चाहिए Upgrade from Ubuntu 11.04 to Ubuntu 11.04। इस विकल्प को स्वीकार करें, और यह आपके लिए सबसे दर्दनाक तरीके से उबंटू को फिर से स्थापित करेगा।
user4124

13
अभी-अभी आपने सबक सीखा है। /निर्देशिका को लक्ष्य के रूप में निर्दिष्ट करने के लिए आपको निर्देशिका नाम के अंत में लिखने की आवश्यकता नहीं है । यह एक बुरी आदत है , यह मत करो, कभी नहीं ! ., वैध निर्देशिका के नाम से ही है संलग्न करने के लिए कोई जरूरत नहीं है /इसे करने के लिए। अगर हर कोई इस नियम का पालन करता है, तो बहुत गलत sudoसंचालन का रूट डायरेक्टरी पर कोई प्रभाव नहीं पड़ेगा, इसलिए उनके सिस्टम को कोई नुकसान नहीं होगा। यह मत करो!
ulidtko

3
@ fl00r, हाँ। यह एक निर्देशिका नाम है जिसका अर्थ यह है, या "वर्तमान" निर्देशिका है। cd ., उदाहरण के लिए, कुछ भी नहीं करता है। ls .के रूप में ही है ls। इसके अलावा, ..एक निर्देशिका नाम है जिसका अर्थ है "जनक .", और आप शायद यह पहले से ही जानते थे।
ulidtko

2
@ulidtko: /अंत में उपयोग नहीं करने के लिए एक अपवाद है । यदि आप केवल निर्देशिका के लिए pathname विस्तार करना चाहते हैं। वर्तमान निर्देशिका के अंदर लिस्टिंग निर्देशिका का उदाहरण:echo */
pabouk

जवाबों:


57

संक्षेप में: आप अपने सिस्टम को पुनर्स्थापित नहीं कर सकते।

मेरा मतलब है, पॉज़िक्स अनुमतियों का उपयोग किया जाता है और बहुत अधिक निर्भर करता है; फाइलसिस्टम में ऐसे स्थानों की भीड़ है जहाँ गलत अनुमतियाँ OS (SUID झंडे) को तोड़ती हैं या इससे भी बदतर, इसे सुरक्षा-वार ( /etc/ssh/ssh_host_rsa_key) उजागर करती हैं जबकि यह ठीक काम करता प्रतीत होता है।

इसलिए, इस तरह की वसूली ठीक से करना मुश्किल है। एक बात याद आती है - और आप इसे पेंच करते हैं। आपने पहले से ही अपनी sudo chmodकमांड को खराब कर दिया है (यदि आपके बजाय आपका दोस्त है , तो वह कुछ लिनक्स सबक भी सीख सकता है,) - और यह एक कमांड का एक बहुत ही सरल है। उचित वसूली अधिक आदेशों और अधिक सतर्कता के रास्ते की मांग करेगी। भले ही आप किसी की स्क्रिप्ट का इस्तेमाल करें।

इसलिए मुझ पर भरोसा रखो, बस पुनः स्थापित करें। यह एक सुरक्षित शर्त है और आपको मुसीबत से बाहर रखने की गारंटी है।


अंत में, कुछ युक्तियां यहां प्रासंगिक हैं।

पहली: यदि आप अगली बार एक अलग विभाजन पर अपनी स्थापना करते हैं/home तो reinstalls कम दर्दनाक होगा । दरअसल, वे एक हवा होंगे।

दूसरा: VirtualBox जैसी वर्चुअल मशीन में पागल लिनक्स साइंस करने पर विचार करें , और अपने स्नैपशॉट को करें।

तीसरा: chmod -R .काम करता है। एक डॉट अपने आप .में मान्य निर्देशिका नाम है। उस स्लैश को जोड़ने की कोई वास्तविक आवश्यकता नहीं है। आप बिंदु को पूरी तरह से लंघन करने के भयावह जोखिम से बच सकते थे;
महज chmod: missing operand after ‘755’वीएस एक बर्बाद प्रणाली।


1
आह्ह :) बहुत दुख हुआ।
fl00r

14
वैसे आप हर फ़ाइल के लिए किसी अन्य सिस्टम से सभी अनुमतियां प्राप्त कर सकते हैं , लेकिन ऐसा करना इतना काम है कि यह शायद आसान हो जाएगा और बस को पुनर्स्थापित करना सुरक्षित होगा।
ओली

2
और दुखी मत हो! महान शक्ति के साथ महान जिम्मेदारी आती है
ulidtko

हाँ, मैंने इसके साथ अपने लैपटॉप को नष्ट कर दिया ... कमाल है कि आप आसानी से एक लिनक्स आधारित मशीन को कैसे नष्ट कर सकते हैं।
एमैनुएल

@ महान शक्ति के साथ amanuel2 महान जिम्मेदारी आता है। आप जो टाइप करते हैं, उसे देखें; sudoइसका मतलब है कि आपको दो बार जांच करनी होगी।
ulidtko

26

मैंने लिखा है और कई वर्षों से रूबी लिपियों के एक जोड़े को rsyncअनुमति और स्वामित्व के लिए उपयोग कर रहा हूं । स्क्रिप्ट get-filesystem-aclसभी फ़ाइलों की पुनरावृत्ति करके सभी जानकारी एकत्र करती है और सभी को फ़ाइल में डाल देती है .acl। स्क्रिप्ट .acl-restoreपढ़ा जाएगा .aclऔर सभी लागू chownकी और chmodके।

आप get-filesystem-aclइसी तरह के उबंटू इंस्टॉलेशन पर चल सकते हैं और फिर .aclफाइल को अपने चोमोड-डैमेज बॉक्स पर कॉपी , डाल .aclऔर .acl-restore/ और रन कर सकते हैं .acl-restore

आपको रूट तय करने की आवश्यकता होगी ताकि sudoमार्को सिप्पी ने सुझाव दिया हो।

मैं .aclअपने उबंटू के लिए फाइल तैयार कर सकता हूं और आपको दे सकता हूं।

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

उबुन्टु 11.04। लेकिन मैंने इसे पहले ही पुनः इंस्टॉल कर लिया है। धन्यवाद!
fl00r

आपकी स्क्रिप्ट विफल है जैसा owner_idकि अपरिभाषित है
एलिरन मलका

8
थोड़े एक overkill ... मिल रहा है काफी अच्छी तरह से है कि:find SOME_DIR -depth -printf 'chmod %m %p\n' > saved_permission
reflog

12

लंबे समय में: आप कर सकते हैं। आपको एक लाइव सीडी से फ़ाइल सिस्टम को माउंट करने की आवश्यकता होगी और उपयुक्त स्थानों में अनुमतियों को वापस करना शुरू करना होगा। sudo chmod u+s /usr/bin/sudoलाइव प्राप्त करने के लिए आप कम से कम सूडो को प्राप्त कर सकते हैं, जबकि आप LiveCD सत्र में इसे चलाना चाहते हैं - यह रूट रूट तय करना होगा।

हालाँकि, सिस्टम को केवल रीइंस्टॉल करना आसान होगा।


4

मैं सभी पैकेजों को पुन: स्थापित करने का प्रयास करूंगा apt-get install --reinstall, संभवत: आउटपुट का उपयोग करके dpkg --get-selections | grep installउनमें से एक सूची प्राप्त करने के लिए।


यह एक बुरा विचार नहीं है, लेकिन आपको उन चीजों को बाहर करने की आवश्यकता होगी जो स्वचालित रूप से स्थापित हैं या आप स्थायी रूप से उन पैकेजों के साथ समाप्त हो जाएंगे (भले ही आपने आश्रित पैकेजों को हटा दिया हो) ... लेकिन फिर उन्हें पुनः इंस्टॉल नहीं किया जाएगा। मजबूत। शायद पहले स्वचालित पैकेजों की सूची प्राप्त करना, फिर प्रत्येक पैकेज को फिर से इंस्टॉल करना फिर ऑटो की सूची से गुजरना, उन्हें ऑटो के रूप में फिर से चिह्नित करना।
ओली

@ ओली - (कुछ नहीं) जिन्हें चलाने से हल किया जा सकता है sudo apt-get autoremove?
विल्फ

@Wilf नहीं - autoremoveकेवल उन संकुल को हटाता है जिन्हें आपने मैन्युअल रूप से संस्थापित नहीं किया है।
दिमित्री ग्रिगोरीव

वहां मौजूद apt-mark auto $pkg/ apt-mark manual $pkgजो आपको प्रति-पैकेज "मैन्युअल रूप से स्थापित / स्वचालित" की स्थिति को संशोधित करने की अनुमति देता है।
ulidtko

3

ठीक है, मैंने इसका परीक्षण नहीं किया है (इसलिए अपने जोखिम पर उपयोग करें), लेकिन यह अभी भी काम कर सकता है। जब मुझे मौका मिलेगा तो मैं इसे एक आभासी मशीन में देखूंगा:

सबसे पहले, अभी भी काम कर रहे सिस्टम में, मैंने एक सूची में सभी फ़ाइल अनुमतियाँ प्राप्त करने के लिए निम्नलिखित किया, /home/निर्देशिका को छोड़ दिया :

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

यह सिस्टम पर प्रत्येक फ़ाइल या निर्देशिका के लिए अनुमतियों और फ़ाइल नाम को मुद्रित करेगा, इसके बाद एक \0चरित्र (यह बाद में जरूरी है कि नए नाम वाले अजीब फ़ाइल नामों से निपटने के लिए)।

फिर, एक सिस्टम पर जहां फ़ाइल अनुमतियों से समझौता किया गया है:

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

के fileper.logरूप में $permऔर फ़ाइल नाम के रूप में अनुमतियों को सहेजने $fileऔर फिर फ़ाइल (या निर्देशिका) की अनुमतियों को जो कुछ भी सूचीबद्ध किया गया है , उसे पढ़ेगा ।fileper.log


यहाँ ध्यान देने योग्य कुछ बातें:

  • फ़ाइल में आउटपुट करते समय: /tmp/fileper.logआप कस्टम सेटिंग्स, और खरीद, आदि की सूची बना सकते हैं।
  • आप बूट करने या कमांड चलाने में सक्षम नहीं हो सकते हैं,

मेरा सुझाव है कि आपके डिस्क पर आपके पास जो लिनक्स संस्करण है, उसके साथ एक लाइवसीडी बूट करें, कमांड चलाएं, उस स्थान को संशोधित करें जहां आपके पास स्थानीय डिस्क माउंट है, और दूसरी कमांड चलाएं!


मैंने परीक्षण किया है कि जब उबंटू सीडी / यूएसबी से बूट किया जाता है, तो मैं डिस्क को प्रारूपित नहीं करने का विकल्प चुन सकता हूं, जिसका अर्थ है कि यह /निर्देशिका में सब कुछ बदल देगा , लेकिन/home/ निर्देशिका को छोड़ दें । मतलब आपके उपयोगकर्ताओं के पास एप्लिकेशन / DATA (संगीत, वीडियो, दस्तावेज़) का कॉन्फ़िगरेशन अभी भी बरकरार रहेगा। और सिस्टम फाइलों को बदलकर, chmodवहां उचित संख्या पर सेट किया जाता है।


1
chmod $(echo $LINE)सिर्फ के बजाय क्यों chmod $LINE? इसके अलावा, आप बस का उपयोग कर सकते findबिना stat: find … -printf "%#m %p\n"। बेहतर अभी तक, आप पूरी कमांड बना सकते हैं: find … -printf "chmod %#m %p\n"फिर फ़ाइल को स्क्रिप्ट के रूप में निष्पादित करें।
मुरु

यह खोज लाइन काम नहीं कर रही है जैसा कि यह है, यह होना चाहिए michael@NEXUS-TWO:~$ sudo find / -name '*' -exec stat -c "%a %n" {} \; >> /tmp/fileper.logलेकिन फिर भी यह चलता है /procऔर कुछ अन्य स्थानों पर जो आप अपनी सूची में नहीं चाहते हैं।
वीडियोनौथ

@ मरमू ने रात के मध्य में यह लिखा। कोड को संपादित करेंगे ...
ब्लेड 19899

परीक्षण करने में सक्षम नहीं, उपयोगकर्ता इनपुट पर निर्भर करेगा
ब्लेड 19899

2

(मुझे पता है कि मुझे जवाब में टिप्पणी नहीं करनी चाहिए, लेकिन टिप्पणी करने के लिए पर्याप्त प्रतिष्ठा नहीं है।)

ब्लेड19899 के उत्तर ने मेरे लिए सिम्बलिंक को छोड़कर काम किया। उदा। इसने 755 / बिन / बैश पर लागू किया, लेकिन फिर 777 को सिमलिंक / बिन / आरबाश पर लागू किया, प्रभावी रूप से 777-इंग / बिन / बैश।

जैसा कि मेरे पास पहले से ही fileper.log फ़ाइल थी, मैंने केवल गंतव्य-अंत कमांड को संशोधित किया था:

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

यदि आपके पास अनुमतियों का बैकअप है, तो क्यों न केवल एक पूर्ण बैकअप बनाएं और ज़रूरत पड़ने पर इसे पुनर्स्थापित करें? यह सिर्फ गलती से नहीं बल्कि किसी भी कमांड रन के मामले में आपको बचाएगा chmod
दिमित्री ग्रिगोरीव

> ... effectively 777-ing /bin/bash- नोप; यह कैसे काम करता है। क्या आप कह रहे हैं कि मैं /usr/bin/aptअपनी खुद की चीज़ को एक गैर-रूट उपयोगकर्ता के रूप में बदल सकता हूँ , बस इसे 777 सिमिलिंक के माध्यम से लिखकर? :) कुछ महत्वपूर्ण सोच व्यायाम करें; सहानुभूति नहीं कर सकते, और इस तरह से काम नहीं करते। सिमिलिंक के लिए 777 अनुमतियां सामान्य और सामान्य हैं।
ulidtko

2

आप के साथ अनुमतियों को पुनर्स्थापित करने का प्रयास कर सकते हैं apt-get

यदि आप इन कमांडो को सुडो के साथ नहीं चला सकते हैं तो आपको रिकवरी मोड को बूट करने और रूट के रूप में चलाने की आवश्यकता हो सकती है।

पुनर्प्राप्ति मोड को बूट करने के लिए https://wiki.ubuntu.com/RecoveryMode देखें

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

नोट: यह मूल रूप से उबंटू मंचों पर पोस्ट किया गया था, लेकिन मुझे मूल पोस्ट नहीं मिली।

क्रम में, कोशिश करें

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

यदि वह विफल रहता है:

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

और अंत में, अंतिम उपाय के रूप में,

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

Apt-get का उपयोग करना

यहाँ प्रासंगिक स्निप, EDR for CORRECTNESS और रिफॉर्मैटेड है:

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

मान लीजिए कि आपको कुछ पैकेजों के बारे में संदेश मिलते हैं जिन्हें फिर से स्थापित नहीं किया जा सकता है, और कमांड विफल हो जाता है। यहाँ प्रश्न में संकुल लंघन द्वारा इसे ठीक करने का एक तरीका है:

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

और अंत में, यदि आपको किसी तरह इतनी सारी चीजें स्थापित करनी चाहिए कि उपरोक्त आदेश यह कहते हुए विफल हो जाए कि आपकी तर्क सूची बहुत लंबी है, तो यहां ठीक है, जो आपके द्वारा पसंद किए जाने की तुलना में कई गुना अधिक हो जाएगी।

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

नोट -yऔर --force-yesविकल्प, जो apt-getआपको बार-बार संकेत देने से रोकेंगे। ये हमेशा मज़ेदार विकल्प होते हैं, यदि आप सुनिश्चित हैं कि आप जानते हैं कि आप क्या कर रहे हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.