如果我不小心在系统目录(/,/ etc,…)上运行命令“chmod -R”怎么办?
我意外地跑了
sudo chmod 755 -R /
代替
sudo chmod 755 -R ./
几秒钟后我停了下来,但现在出现了一些问题
sudo: must be setuid root
如何恢复权限?
简而言之: 您不能重新安装系统。
我的意思是,Posix权限被大量使用和依赖; 文件系统中有很多地方错误的权限会破坏操作系统(SUID标志),甚至更糟糕的是,它在安全性方面( /etc/ssh/ssh_host_rsa_key
)暴露出来,而它似乎工作正常。
因此,这样的恢复很难做得很好。 想念一件事 – 你搞砸了。 你已经搞砸了你的sudo chmod
命令(如果这是你的朋友而不是你,她也可以学习一些Linux课程) – 这是一个非常简单的命令。 适当的恢复需要更多的命令和更多的警惕。 即使你使用一些人的脚本。
所以相信我,只需重新安装。 这是一个安全的赌注,保证让你摆脱困境。
最后,这里有一些相关提示。
首先:如果下次在单独的分区上设置/home
,重新安装将不那么痛苦。 实际上,他们将是一件轻而易举的事。
第二:考虑在像VirtualBox这样的虚拟机中做疯狂的Linux科学 ,然后做你的快照。
第三: chmod -R .
作品。 没有必要附加斜线。 你可以避免在主要地跳过点的灾难性风险;
仅仅是chmod: missing operand after '755'
一个破败的系统chmod: missing operand after '755'
。
我写了几年并使用了几个Ruby脚本来rsync
权限和所有权。 脚本get-filesystem-acl
通过递归遍历所有文件来收集所有信息,并将其全部放入文件.acl
。 脚本.acl-restore
将读取.acl
并应用所有chown
和chmod
。
您可以在类似的Ubuntu安装上运行get-filesystem-acl
,然后将.acl
文件复制到chmod-damaged框,将.acl
和.acl-restore
到/中,然后运行.acl-restore
。
你需要拥有root权限,以便像Marco Ceppi建议的那样修复你的sudo
。
我可以为我的Ubuntu生成并提供.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
总之:你可以。 您需要从Live CD安装文件系统,然后开始在适当的位置恢复权限。 至少要获得sudo,你需要在LiveCD会话中运行sudo chmod u+s /usr/bin/sudo
– 这将修复必须的setuid root。
但是,简单地重新安装系统可能会更容易。
我会尝试使用apt-get install --reinstall
重新安装所有软件包,可能使用dpkg --get-selections | grep install
的输出dpkg --get-selections | grep install
dpkg --get-selections | grep install
来获取它们的列表。
好吧,我没有测试过这个(所以请自行承担使用风险),但它仍然有用。 当我有机会在虚拟机中测试时:
首先,在一个仍在工作的系统中,我执行以下操作以获取列表中的所有文件权限,跳过/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
列出的fileper.log
这里有几点需要注意:
- 在输出到文件:
/tmp/fileper.log
,您可能会列出自定义设置和proc等。 - 您可能无法启动或运行命令,
我建议用你的磁盘上的Linux版本启动一个LiveCD,运行命令,修改你安装本地磁盘的路径,然后运行第二个命令!
我测试过,当从Ubuntu CD / USB启动时,我可以选择不格式化磁盘,这意味着它将替换/
目录中的所有内容, 但跳过/home/
目录。 这意味着您的用户将仍然保持应用程序/数据(音乐,video,文档)的配置。 通过替换系统文件, chmod
被设置为适当的数字。
(我知道我不应该在答案中发表评论,但没有足够的声誉来发表评论。)
blade19899的答案对我有用,除了符号链接。 例如,它将755应用于/ bin / bash,但随后将777应用于symlink / bin / rbash,实际上是777-ing / bin / bash。
因为我已经有了fileper.log文件,所以我只修改了destination-end命令:
while IFS=: read -r -d '' perm file; do if [[ ! -L "$file" ]]; then chmod "$perm" "$file" fi done < /tmp/fileper.log
您可以尝试使用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
这是相关的剪辑,编辑正确并重新格式化:
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
一次又一次地提示你。 如果你确定你知道自己在做什么,这些都是有趣的选择。