실수로 시스템 디렉토리 (/, / etc,…)에서“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 하면 다시 설치하기가 쉽지 않습니다 . 실제로, 그들은 바람이 될 것입니다.

둘째 : VirtualBox와 같은 가상 머신 에서 미친 리눅스 과학 을 고려하고 스냅 샷을 작성하십시오.

셋째 : chmod -R .작동합니다. 점 자체 .는 유효한 디렉토리 이름입니다. 슬래시를 추가 할 필요는 없습니다. 점을 완전히 건너 뛰는 치명적인 위험을 피할 수있었습니다.
단순한 chmod: missing operand after ‘755’폐허 시스템 VS.


1
아아 :) 너무 슬프다.
fl00r

14
그럼 당신이 할 수 있는 다른 시스템에서 모든 파일에 대해 모든 권한을 받고 있지만 수행하여이는 아마 다시 설치하기 쉽고 안전 할 거라고 너무 많은 일입니다.
Oli

2
그리고 슬퍼하지 마십시오! 큰 힘을 가진 큰 책임이 온다
ulidtko

그래, 난 그냥 내 노트북을 파괴 ... 리눅스 기반 시스템을 쉽게 파괴하는 방법 놀라운.
amanuel2

큰 힘을 가진 @ amanuel2는 큰 책임을집니다. 입력 한 내용을 확인하십시오. sudo두 번 확인해야 함을 의미합니다.
ulidtko

26

필자는 몇 년 동안 몇 가지 루비 스크립트를 rsync사용 권한과 소유권 으로 작성해 왔습니다 . 스크립트 get-filesystem-acl는 모든 파일을 재귀 적으로 순회하여 모든 정보를 수집하여 파일에 모두 넣습니다 .acl. 스크립트 .acl-restore.acl모든 적용 chown의와 chmod의를.

당신은 실행할 수 있습니다 get-filesystem-acl비슷한 우분투 설치에 다음을 복사 .acl넣어, 당신의 chmod를 손상된 상자에 파일 .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가 정의되지 않은 상태 로 실패
Eliran Malka

8
좀 과잉 ... 찾기 아주 잘 않습니다 :find SOME_DIR -depth -printf 'chmod %m %p\n' > saved_permission
reflog

12

길게는 : 할 수 있습니다. Live CD에서 파일 시스템을 마운트하고 적절한 위치에서 권한을 되돌리기 시작해야합니다. sudo를 다시 가져 오려면 최소한 sudo chmod u+s /usr/bin/sudoLiveCD 세션에서 실행 해야합니다. 그러면 setuid 루트가 수정됩니다.

그러나 단순히 시스템을 다시 설치하는 것이 더 쉬울 것입니다.


4

로 모든 패키지를 다시 설치하려고 시도 apt-get install --reinstall하고 출력을 사용하여 패키지 dpkg --get-selections | grep install목록을 얻을 수 있습니다.


이것은 나쁜 생각은 아니지만 자동으로 설치되거나 종속 패키지를 제거한 경우에도 해당 패키지로 영구적으로 종료되는 항목을 제외해야하지만 다시 설치되지는 않습니다. 힘든 것. 아마도 자동 패키지 목록을 먼저 얻은 다음 모든 패키지를 다시 설치하고 자동 목록을 통해 자동으로 다시 표시하십시오.
Oli

@Oli-(일부) 실행하지 않아도 해결되지 sudo apt-get autoremove않습니까?
Wilf

@Wilf 아니요- 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 등을 나열 할 수 있습니다.
  • 부팅하거나 명령을 실행하지 못할 수 있습니다.

내가 제안하는 것은 디스크에있는 Linux 버전으로 LiveCD를 부팅하고 명령을 실행하고 로컬 디스크가 마운트 된 경로를 수정 한 다음 두 번째 명령을 실행하는 것입니다!


우분투 CD / USB에서 부팅 할 때 디스크를 포맷하지 않도록 선택할 수 있습니다. 즉, /디렉토리의 모든 것을 대체 하지만 디렉토리는 건너 뜁니다 /home/. 즉, 사용자는 여전히 앱 / 데이터 (음악, 비디오, 문서) 구성이 그대로 유지됩니다. 그리고 시스템 파일을 교체하면 chmod적절한 번호로 설정됩니다.


1
chmod $(echo $LINE)대신에 chmod $LINE? 또한 : find없이 사용할 수 있습니다 . 더 나은 방법은 전체 명령을 생성 한 다음 파일을 스크립트로 실행하는 것입니다. statfind … -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

테스트 할 수
없고

3

(나는 대답에 언급해서는 안되지만 의견을 말할만큼 평판이 좋지는 않다는 것을 알고 있습니다.)

blade19899의 답변은 symlinks를 제외하고 저에게 효과적이었습니다. 예를 들어 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 

권한 백업이있는 경우 전체 백업을 만들어 필요할 때 복원하는 것이 어떻습니까? 그것은 단지 명령이 아닌 실수로 명령이 실행되는 경우 당신을 구할 것입니다 chmod.
Dmitry Grigoryev

2

으로 권한 복원을 시도 할 수 있습니다 apt-get.

sudo를 사용하여 이러한 명령을 실행할 수 없으면 복구 모드로 부팅하여 루트로 실행해야 할 수 있습니다.

복구 모드로 부팅하려면 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 사용

다음은 수정 및 수정 된 관련 코드입니다.

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하면 계속해서 계속 묻는 메시지 가 표시되지 않습니다 . 자신이하는 일을 확실히 알고 있다면 항상 재미있는 옵션입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.