ถ้าฉันเรียกใช้คำสั่ง“ chmod -R” โดยไม่ตั้งใจในไดเรกทอรีระบบ (/, / ฯลฯ , ... )


56

ฉันวิ่งไปโดยไม่ตั้งใจ

sudo chmod 755 -R /

แทน

sudo chmod 755 -R ./

ฉันหยุดมันหลังจากไม่กี่วินาที แต่ตอนนี้มีปัญหาบางอย่างเช่น

sudo: must be setuid root

ฉันจะยกเลิกการอนุญาตกลับคืนได้อย่างไร?


18
โอ้ที่รัก ... sudoหมายความว่าคุณคิดสองครั้งว่าจะทำอะไร!
antivirtel

2
วิธีที่ง่ายที่สุดคือติดตั้งใหม่ วาง LiveCD / USB และที่หน้าจอที่ขอให้คุณแบ่งพาร์ติชันดิสก์ควรให้ตัวเลือกแก่Upgrade from Ubuntu 11.04 to Ubuntu 11.04คุณ ยอมรับตัวเลือกนี้และจะติดตั้ง Ubuntu ใหม่ให้คุณอย่างมีประสิทธิภาพด้วยวิธีที่ไม่เจ็บปวดที่สุด
user4124

13
ตอนนี้คุณได้เรียนรู้บทเรียนแล้ว คุณไม่จำเป็นต้องเขียน/ในตอนท้ายของชื่อไดเรกทอรีเพื่อระบุไดเรกทอรีเป็นเป้าหมาย มันเป็นนิสัยที่ไม่ดีไม่ทำไม่เคย ! .มีด้วยตัวเองชื่อไดเรกทอรีที่ถูกต้องไม่มีความจำเป็นที่จะผนวก/กับมัน หากทุกคนปฏิบัติตามกฎนี้sudoการดำเนินการที่พิมพ์ผิดอย่างมากจะไม่มีผลกับไดเรกทอรีรูทดังนั้นจะไม่มีอันตรายใด ๆ เกิดขึ้นกับระบบของพวกเขา อย่าทำมัน!
ulidtko

3
@ fl00r ใช่ มันเป็นชื่อไดเรกทอรีซึ่งหมายถึงสิ่งนี้หรือไดเรกทอรี "ปัจจุบัน" cd .ตัวอย่างเช่นไม่ทำอะไรเลย เป็นเช่นเดียวกับls . lsนอกจากนี้ยัง..เป็นชื่อไดเรกทอรีซึ่งหมายถึง "ผู้ปกครองของ." และคุณอาจรู้แล้ว
ulidtko

2
@ulidtko: มีข้อยกเว้นที่ไม่ควรใช้/ในตอนท้าย หากคุณต้องการขยายชื่อพา ธ สำหรับไดเรกทอรีเท่านั้น ตัวอย่างของการแสดงรายการไดเรกทอรีภายในไดเรกทอรีปัจจุบัน:echo */
pabouk

คำตอบ:


56

ในระยะสั้น: คุณไม่สามารถติดตั้งระบบของคุณใหม่

ฉันหมายถึงการอนุญาตให้ใช้ Posix และการใช้งานอย่างหนัก มีสถานที่มากมายในระบบไฟล์ที่การอนุญาตที่ผิดจะทำลาย OS (ค่าสถานะ SUID) หรือแย่ลงทำให้ความปลอดภัย ( /etc/ssh/ssh_host_rsa_key) ในขณะที่ดูเหมือนว่าจะทำงานได้ดี

ดังนั้นการกู้คืนดังกล่าวจึงทำได้ยาก พลาดสิ่งหนึ่งไป - แล้วคุณก็ทำมันขึ้น คุณแล้วเมาขึ้นของsudo chmodคำสั่ง (ถ้าเป็นเพื่อนของคุณมากกว่าที่คุณเธอเช่นกันอาจจะเรียนรู้บทเรียนลินุกซ์บางเกินไป) - และที่ง่ายมากของคำสั่ง การกู้คืนที่เหมาะสมจะต้องใช้คำสั่งทางและระมัดระวังมากขึ้น แม้ว่าคุณจะใช้สคริปต์ของใครบางคน

เชื่อใจฉันแค่ติดตั้งใหม่ มันเป็นเดิมพันที่ปลอดภัยและรับประกันว่าจะทำให้คุณหมดปัญหา


ในที่สุดเคล็ดลับที่เกี่ยวข้องที่นี่

ข้อแรก: การติดตั้งซ้ำจะเจ็บปวดน้อยลงหากคุณตั้งค่า/homeในพาร์ติชันแยกต่างหากในครั้งต่อไป ที่จริงแล้วพวกเขาจะง่าย

ข้อที่สอง: พิจารณาทำวิทยาศาสตร์ Linux ที่บ้าคลั่งในเครื่องเสมือนเช่น VirtualBox และทำสแน็ปช็อตของคุณ

ที่สาม: chmod -R .งาน จุดด้วยตัวเอง.เป็นชื่อไดเรกทอรีที่ถูกต้อง ไม่จำเป็นต้องผนวกเครื่องหมายทับนั้นอีก คุณสามารถหลีกเลี่ยงความเสี่ยงจากภัยพิบัติที่จะข้ามจุดได้อย่างสิ้นเชิง
เพียงchmod: missing operand after ‘755’VS ระบบที่ถูกทำลาย


1
Ahhh :) เศร้ามาก
fl00r

14
คุณทำได้โดยได้รับอนุญาตทั้งหมดสำหรับทุกไฟล์จากระบบอื่น แต่การทำเช่นนี้เป็นการทำงานที่มากจนอาจจะง่ายกว่าและปลอดภัยกว่าเพียงแค่ติดตั้งใหม่
Oli

2
และอย่าเศร้า! ด้วยพลังอันยิ่งใหญ่มาพร้อมความรับผิดชอบที่ยอดเยี่ยม
ulidtko

ใช่ฉันเพิ่งทำลายแล็ปท็อปของฉันด้วยสิ่งนี้ ... น่าประหลาดใจที่คุณสามารถทำลายเครื่องที่ใช้ลินุกซ์ได้อย่างง่ายดาย
amanuel2

@ amanuel2 ที่มีพลังอันยิ่งใหญ่มาพร้อมความรับผิดชอบที่ยอดเยี่ยม ดูสิ่งที่คุณพิมพ์; sudoหมายความว่าคุณต้องตรวจสอบสองครั้ง
ulidtko

26

ฉันเขียนและใช้งานสคริปต์ Ruby มาหลายปีเพื่อให้rsyncอนุญาตและเป็นเจ้าของ สคริปต์เก็บรวบรวมข้อมูลทั้งหมดด้วยซ้ำภายในทุกไฟล์และทำให้ทุกอย่างลงในแฟ้มget-filesystem-acl .aclสคริปต์.acl-restoreจะอ่าน.aclและนำไปใช้ทั้งหมดchown'และchmod' s

คุณสามารถเรียกใช้get-filesystem-aclในการติดตั้งอูบุนตูที่คล้ายกันและจากนั้นคัดลอกมากกว่า.aclไฟล์ไปยังกล่อง chmod เสียหายของคุณใส่.aclและ.acl-restoreใน / .acl-restoreและการทำงาน

คุณจะต้องมีรูทเพื่อแก้ไขsudoตามที่ Marco Ceppi แนะนำ

ฉันสามารถสร้างและให้.aclไฟล์สำหรับ Ubuntu ของคุณ

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 แต่ฉันติดตั้งใหม่แล้ว ขอบคุณ!
fl00r

สคริปต์ของคุณล้มเหลวเนื่องจากowner_idไม่ได้กำหนด
Eliran Malka

8
ค่อนข้าง overkill ... พบว่าค่อนข้างดี:find SOME_DIR -depth -printf 'chmod %m %p\n' > saved_permission
reflog

12

ในระยะยาว: คุณสามารถ คุณจะต้องติดตั้งระบบไฟล์จาก Live CD และเริ่มคืนค่าสิทธิ์ในตำแหน่งที่เหมาะสม อย่างน้อยที่สุดเพื่อให้ได้ sudo กลับมาคุณจะต้องทำงานsudo chmod u+s /usr/bin/sudoในขณะที่อยู่ในเซสชัน LiveCD ซึ่งจะต้องแก้ไข setuid root

อย่างไรก็ตามอาจเป็นเรื่องง่ายกว่าที่จะติดตั้งระบบใหม่


4

ฉันจะพยายามติดตั้งแพ็กเกจทั้งหมดอีกครั้งด้วยapt-get install --reinstallอาจใช้ผลลัพธ์ของdpkg --get-selections | grep installเพื่อรับรายการเหล่านั้น


นี่ไม่ใช่ความคิดที่ไม่ดี แต่คุณจะต้องแยกสิ่งต่าง ๆ ที่ติดตั้งโดยอัตโนมัติหรือคุณจะจบลงด้วยแพ็คเกจเหล่านั้นอย่างถาวร (แม้ว่าคุณจะลบแพ็คเกจที่ต้องพึ่งพา) ... แต่แล้วพวกเขาก็จะไม่ได้รับการติดตั้งใหม่ เหนียวหนึ่งอัน อาจได้รับรายชื่อแพ็คเกจอัตโนมัติก่อนจากนั้นติดตั้งใหม่ทุกแพ็คเกจแล้วทำรายการรถยนต์และทำเครื่องหมายใหม่เป็นอัตโนมัติ
Oli

@Oli - จะไม่แก้ไข (บางส่วน) ที่จะทำงานได้sudo apt-get autoremoveหรือไม่
วิลฟ์

@Wilf No - autoremoveลบเฉพาะแพ็คเกจที่คุณไม่ได้ติดตั้งด้วยตนเอง
Dmitry Grigoryev

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คุณอาจจะแสดงรายการการตั้งค่าที่กำหนดเองและ proc ฯลฯ
  • คุณอาจไม่สามารถบู๊ตหรือรันคำสั่งได้

สิ่งที่ฉันอยากจะแนะนำคือการบูท LiveCD ด้วย Linux เวอร์ชันที่คุณมีบนดิสก์ของคุณรันคำสั่งแก้ไขพา ธ ไปยังตำแหน่งที่คุณติดตั้งโลคัลดิสก์แล้วเรียกใช้คำสั่งที่สอง!


ฉันได้ทดสอบแล้วว่าเมื่อบูทจากอูบุนตู CD / USB ฉันสามารถเลือกที่จะไม่ฟอร์แมตดิสก์ซึ่งหมายความว่ามันจะแทนที่ทุกอย่างใน/ไดเรกทอรีแต่ข้าม/home/ไดเรกทอรี หมายความว่าผู้ใช้ของคุณจะมีการกำหนดค่าแอพ / DATA (เพลง, วิดีโอ, เอกสาร) ยังคงเหมือนเดิม และโดยการแทนที่ไฟล์ระบบchmodจะมีการตั้งค่าเป็นจำนวนที่เหมาะสม


1
ทำไมchmod $(echo $LINE)แทนที่จะเป็นแค่chmod $LINE? นอกจากนี้คุณยังสามารถใช้เพียงfindโดยไม่ต้อง:stat find … -printf "%#m %p\n"ยังดีกว่าคุณสามารถสร้างคำสั่งทั้งหมด: find … -printf "chmod %#m %p\n"จากนั้นเรียกใช้ไฟล์เป็นสคริปต์
muru

บรรทัดการค้นหาไม่ทำงานตามที่ควรจะเป็นmichael@NEXUS-TWO:~$ sudo find / -name '*' -exec stat -c "%a %n" {} \; >> /tmp/fileper.logแต่ก็เช่นกันมันทำงานได้ดี/procและสถานที่อื่น ๆ ที่คุณอาจไม่ต้องการในรายการของคุณ
Videonauth

@muru เขียนสิ่งนี้ในกลางดึก จะแก้ไขรหัส ...
Blade19899

ไม่สามารถทดสอบจะขึ้นอยู่กับการป้อนข้อมูลของผู้ใช้
Blade19899

3

(ฉันรู้ว่าฉันไม่ควรแสดงความคิดเห็นในคำตอบ แต่ชื่อเสียงไม่เพียงพอที่จะแสดงความคิดเห็น)

คำตอบของ blade19899 ทำงานสำหรับฉันยกเว้น symlink เช่นใช้ 755 ถึง / bin / bash แต่ใช้ 777 กับ symlink / bin / rbash อย่างมีประสิทธิภาพ 777-ing / bin / bash

เนื่องจากฉันมีไฟล์ fileper.log อยู่แล้วฉันเพิ่งแก้ไขคำสั่งปลายทาง:

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

หากคุณมีการสำรองสิทธิ์ทำไมไม่เพียงทำการสำรองข้อมูลเต็มรูปแบบและเรียกคืนเมื่อจำเป็น ที่จะช่วยให้คุณประหยัดในกรณีของการดำเนินการคำสั่งใด ๆ chmodโดยไม่ได้ตั้งใจไม่ได้เป็นเพียง
Dmitry Grigoryev

2

apt-getคุณสามารถลองกู้คืนสิทธิ์กับ

หากคุณไม่สามารถเรียกใช้คำสั่งเหล่านี้ด้วย sudo คุณอาจต้องบูตไปที่โหมดการกู้คืนและเรียกใช้เป็น root

สำหรับการบูตไปที่โหมดการกู้คืนดูhttps://wiki.ubuntu.com/RecoveryMode

จากhttp://hyperlogos.org/page/Restoring-Permissions-Debian-System

หมายเหตุ: โพสต์นี้ถูกโพสต์บนฟอรัม Ubuntu แต่ฉันหาโพสต์ดั้งเดิมไม่เจอ

ลองตามลำดับ

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

นี่คือ snip ที่เกี่ยวข้อง, แก้ไขสำหรับการแก้ไขและจัดรูปแบบใหม่:

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)'`

และในที่สุดถ้าคุณควรติดตั้งหลายสิ่งหลายอย่างที่คำสั่งด้านบนล้มเหลวในการบอกว่ารายการอาร์กิวเมนต์ของคุณยาวเกินไปนี่คือการแก้ไขซึ่งจะเรียกใช้ apt-get มากกว่าหลายครั้งที่คุณอาจชอบ:

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

จดบันทึก-yและ--force-yesตัวเลือกซึ่งจะหยุดไม่apt-getให้คุณซ้ำแล้วซ้ำอีก สิ่งเหล่านี้เป็นตัวเลือกที่สนุกเสมอหากคุณแน่ใจว่าคุณรู้ว่ากำลังทำอะไรอยู่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.