システムディレクトリ(/、/ 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操作の多くはルートディレクトリに影響を与えないので、システムに害はありません。しないでください!
ウリトコ

3
@ fl00r、はい。これは、これを意味するディレクトリ名、または「現在の」ディレクトリです。cd .たとえば、何もしません。ls .はと同じlsです。また、..は「の親」を意味するディレクトリ名であり.、おそらく既に知っているでしょう。
-ulidtko

2
@ulidtko:/最後に使用しない例外があります。ディレクトリのみのパス名展開を行いたい場合。現在のディレクトリ内のディレクトリのリストの例:echo */
pabouk

回答:


57

つまり、システムを再インストールすることはできません。

つまり、Posixアクセス許可が使用され、大きく依存しています。間違ったアクセス許可がOSを破壊する(SUIDフラグ)、さらに悪いことに、正常に動作/etc/ssh/ssh_host_rsa_keyしているように見えてもセキュリティ面()にさらされるファイルシステムの場所が多数あります。

したがって、このような回復を適切に行うことは困難です。ひとつだけミスします-そして、あなたはそれを台無しにします。あなたはすでにsudo chmodコマンドを台無しにしています(それがあなたよりもあなたの友人なら、彼女もLinuxのレッスンを学ぶかもしれません)-それは非常に単純なコマンドです。適切に回復するには、より多くのコマンドとより多くの警戒が必要です。誰かのスクリプトを使用しても。

だから私を信じて、再インストールするだけです。それは安全な賭けであり、トラブルからあなたを守ることが保証されています。


最後に、ここで関連するいくつかのヒント。

まず次回に別のパーティションにセットアップする/home場合、再インストールの苦痛が少なくなります。実際には、彼らは簡単になります。

2番目:VirtualBoxのような仮想マシンクレイジーなLinux科学を行うことを検討し、スナップショットを作成します。

第三:chmod -R .動作します。ドット自体.は有効なディレクトリ名です。そのスラッシュを追加する必要はありません。ドットを完全にスキップする壊滅的なリスクを回避できたはずです。
単にchmod: missing operand after ‘755’VS台無しにされたシステム。


1
ああ:)とても悲しい。
-fl00r

14
別のシステムからすべてのファイルのすべてのアクセス許可を取得することでできます、これを行うのは非常に多くの作業であるため、再インストールするだけで簡単で安全になります。
オリ

2
悲しいことはありません!大きな力には大きな責任が伴います
ulidtko

ええ、これでラップトップを破壊したばかりです。Linuxベースのマシンを簡単に破壊できるのは驚くべきことです。
amanuel2

大きな力を持つ@ amanuel2には大きな責任が伴います。入力内容に注意してください。sudo2回確認する必要があることを意味します。
ulidtko

26

私は数年間、rsync許可と所有権のためのRubyスクリプトを書いて使用しています。スクリプトget-filesystem-aclは、すべてのファイルを再帰的に走査してすべての情報を収集し、すべてをファイルに格納します.acl。スクリプトは.acl-restore読みます.aclと、すべての適用chownのとchmodのを。

あなたは実行することができますget-filesystem-acl同様のUbuntuのインストールで、その後をコピー.acl入れて、あなたのchmodの損傷ボックスにファイル.aclおよび.acl-restore/で、そして実行します.acl-restore

ルートをsudo取得する必要があるので、Marco Ceppiが提案したように修正してください。

.aclUbuntuのファイルを生成して提供できます。

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未定義のままスクリプトが失敗する
エリランマルカ14

8
ちょっとやり過ぎ... findはそれを非常にうまく行います: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-(一部)を実行しても解決しsudo apt-get autoremoveないでしょうか?
ウィルフ14

@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、カスタム設定、procなどをリストしている可能性があります。
  • 起動またはコマンドを実行できない場合があります。

私がお勧めするのは、ディスク上にあるLinuxバージョンでLiveCDを起動し、コマンドを実行し、ローカルディスクをマウントした場所へのパスを変更し、2番目のコマンドを実行することです。


私はUbuntuのCD / USBから起動したときに、私はそれがですべてを置換する意味、ディスクをフォーマットしないように選択することをテストしている/ディレクトリ、しかしスキップ/home/ディレクトリを。ユーザーの意味するところは、apps / DATA(Music、Video、Documents)の構成はそのままです。そして、システムファイルを置き換えることにより、chmod適切な数に設定されます。


1
なぜchmod $(echo $LINE)代わりにchmod $LINE?また、あなただけ使用することができfindずにstatfind … -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れ、リストには含まれていない可能性のある他の場所も実行されます。
Videonauth

@muruはこれを深夜に書いた。コードを編集します...
blade19899

テストできず、ユーザー入力に依存します
-blade19899

2

(私は答えにコメントすべきではないことを知っていますが、コメントするのに十分な評判はありません。)

blade19899の答えは、シンボリックリンクを除き、私にとってはうまくいきました。たとえば、755を/ bin / bashに適用しましたが、777をシンボリックリンク/ bin / rbashに適用し、事実上/ bin / bashを777します。

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
ドミトリーグリゴリエフ

> ... effectively 777-ing /bin/bash—いいえ。それはそれがどのように機能するかではありません。777シンボリックリンクを介して書き込むだけで、非rootユーザーとして/usr/bin/apt自分のものに置き換えることができると言っていますか?:)いくつかの批判的思考を行使します。シンボリックリンクはそのように機能することはできませんし、機能しません。シンボリックリンクの777パーミッションは一般的で通常のものです。
ulidtko

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の使用

関連する切り抜きは、正確に編集され、再フォーマットされています。

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

再インストールできない一部のパッケージに関するメッセージが表示され、コマンドが失敗したとします。問題のパッケージをスキップして修正する方法の1つを次に示します。

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.