ファイルを除くすべてのディレクトリを再帰的にchmodする方法は?


574

すべてのディレクトリをchmod 755する方法(ファイルはありません)

逆に、ディレクトリのみではなく、ファイルのみを(再帰的に)chmodする方法は?



回答:


801

ディレクトリに読み取りおよび実行権限を再帰的に付与するには:

find /path/to/base/dir -type d -exec chmod 755 {} +

ファイルに再帰的に読み取り権限を付与するには:

find /path/to/base/dir -type f -exec chmod 644 {} +

または、処理するオブジェクトが多数ある場合:

chmod 755 $(find /path/to/base/dir -type d)
chmod 644 $(find /path/to/base/dir -type f)

または、chmod産卵を減らすには:

find /path/to/base/dir -type d -print0 | xargs -0 chmod 755 
find /path/to/base/dir -type f -print0 | xargs -0 chmod 644

7
最初の2つの例は、ファイルが多すぎるディレクトリでは失敗します-bash: /bin/chmod: Argument list too long。最後のコマンドは多くのファイルで機能しますが、使用するときsudoはchmodではなくxargsの前に配置するように注意する必要がありますfind /path/to/base/dir -type d -print0 | sudo xargs -0 chmod 755
。– Agargara

2
また注意することは、これらのコマンドは、包括的な基本ディレクトリの。したがって、上記の例でdirは、755にも設定されます
。– CenterOrbit

2
chmod ... $(find /path/to/base/dir -type ...)名前にスペースが含まれるファイル名では失敗します。
ダンダスカレスク

7
ファイル名のスペースと記号、およびファイル数に関して最も正しい(ただし最速ではない)バージョンはfind /path/to/base/dir -type d -exec chmod 755 {} \;find /path/to/base/dir -type f -exec chmod 644 {} \;)です。
ピーターK

これは、読み取り可能な最初のレイヤーにのみ移動することに注意してください。ディレクトリツリーをさらに深くするには、数回実行する必要があります。
ヘンクポーリー

290

この種の一般的な理由は、ディレクトリを755に、ファイルを644に設定することです。この場合、nikのfind例よりも少し速い方法があります。

chmod -R u+rwX,go+rX,go-w /path

意味:

  • -R =再帰的に;
  • u+rwX =ユーザーは読み取り、書き込み、実行できます。
  • go+rX =グループおよび他のユーザーが読み取りおよび実行できます。
  • go-w =グループと他の人は書くことができません

ここで注意すべき重要なことは、大文字と小文字のX動作が異なることxです。マニュアルでは以下を読むことができます:

ファイルがディレクトリであるか、実行/検索ビットのいずれかが元の(変更されていない)モードに設定されている場合、実行/検索ビット。

つまり、ファイルのchmod u + Xは実行ビットを設定しません。g + Xは、既にユーザーに設定されている場合にのみ設定します。


5
-R =再帰的に。u + rwX =ユーザーは読み取り、書き込み、実行できます。go + rX =グループおよび他のユーザーが読み取りおよび実行できます。=グループW-行くと、他の人の書き込みはできません
Slackerは

23
このパターンはchmod -R 777+Xオプションがファイルの既存の実行ビットをリセットしないため、誰かが行ったときの状況を修正しません。-xを使用すると、ディレクトリがリセットされ、ディレクトリへの下降が防止されます。
アンドリューヴィット

3
@ ring0:私は、提示されたとおりの質問に文字通り答えるつもりはありません-nikはすでにそれを完全にうまく行っています。最も一般的なケースでは、より安価なソリューションを示しています。そして、はい、Xコメントで説明されているように、ファイルとディレクトリに対して異なるパーミッションを取得します。
ボビンス

6
go+rX,go-w->そうでgo=rXはありませんか?
ピエールドレスピネー

5
またchmod u-x,u+X、組み合わせて使用するなどして、ファイルの実行ビットを削除して、ディレクトリに実行ビットを追加することもできます。
w0rp 16

14

ファイルが644に設定され、パスに実行フラグを持つファイルがあることを確認する場合は、最初に実行フラグを削除する必要があります。+ Xは、実行フラグを既に持っているファイルから削除しません。

例:

chmod -R ugo-x,u+rwX,go+rX,go-w path

更新:最初の変更(ugo-x)によりディレクトリが実行不能になり、その下のすべてのファイルが変更されないため、これは失敗したように見えます。


1
これは私にとってはうまくいきますが、なぜそうならないのかわかりません。(確かに、やっただけならそれはchmod -R ugo-x path問題かもしれません。しかし、完全なコマンドは、chmod u+rwX各ディレクトリで下がろうとする前にそれを行います。)しかし、私はそれchmod R u=rw,go=r,a+X pathで十分だと思います。
スコット14

これが適切に機能していることがわかりました。ディレクトリの入力に問題はありませんでした
Someone Somewhere

4

私はこのための小さなスクリプトを自分で書くことにしました。

dirsやファイルのための再帰的なchmodスクリプト— Gist

chmodr.sh

#!/bin/sh
# 
# chmodr.sh
#
# author: Francis Byrne
# date: 2011/02/12
#
# Generic Script for recursively setting permissions for directories and files
# to defined or default permissions using chmod.
#
# Takes a path to recurse through and options for specifying directory and/or 
# file permissions.
# Outputs a list of affected directories and files.
# 
# If no options are specified, it recursively resets all directory and file
# permissions to the default for most OSs (dirs: 755, files: 644).

# Usage message
usage()
{
  echo "Usage: $0 PATH -d DIRPERMS -f FILEPERMS"
  echo "Arguments:"
  echo "PATH: path to the root directory you wish to modify permissions for"
  echo "Options:"
  echo " -d DIRPERMS, directory permissions"
  echo " -f FILEPERMS, file permissions"
  exit 1
}

# Check if user entered arguments
if [ $# -lt 1 ] ; then
 usage
fi

# Get options
while getopts d:f: opt
do
  case "$opt" in
    d) DIRPERMS="$OPTARG";;
    f) FILEPERMS="$OPTARG";;
    \?) usage;;
  esac
done

# Shift option index so that $1 now refers to the first argument
shift $(($OPTIND - 1))

# Default directory and file permissions, if not set on command line
if [ -z "$DIRPERMS" ] && [ -z "$FILEPERMS" ] ; then
  DIRPERMS=755
  FILEPERMS=644
fi

# Set the root path to be the argument entered by the user
ROOT=$1

# Check if the root path is a valid directory
if [ ! -d $ROOT ] ; then
 echo "$ROOT does not exist or isn't a directory!" ; exit 1
fi

# Recursively set directory/file permissions based on the permission variables
if [ -n "$DIRPERMS" ] ; then
  find $ROOT -type d -print0 | xargs -0 chmod -v $DIRPERMS
fi

if [ -n "$FILEPERMS" ] ; then
  find $ROOT -type f -print0 | xargs -0 chmod -v $FILEPERMS
fi

基本的に再帰的なchmodを実行しますが、コマンドラインオプションに多少の柔軟性を提供します(ディレクトリやファイルのアクセス権を設定するか、両方を除外すると自動的にすべてが755-644にリセットされます)。また、いくつかのエラーシナリオもチェックします。

ブログでも書いた。


2

ディレクトリに読み取りおよび実行権限を再帰的に付与するには:

find /path/to/base/dir -type d -exec chmod 755 {} \;

ファイルに再帰的に読み取り権限を付与するには:

find /path/to/base/dir -type f -exec chmod 644 {} \;

正確さの観点からnikの答えを決してアップグレードさせないよりは遅かった。私の解決策は遅くなりますが、ファイル名の任意のシンボルで任意の数のファイルで動作し、sudoで正常に実行できます(ただし、sudoで異なるファイルを検出する可能性があることに注意してください)。


これはnikの回答の格下げです。ニックの答えに何か問題があると思うのはなぜですか?
スコット

@ Scott、nikの答えは(vey)多数のファイルで失敗します。
ピーターK

あなたが間違っていると99%確信しています。あなたの主張を裏付ける証拠を提供できますか?
スコット

はい、確かに私は間違っているようです。find ... +は、行を複数のコマンドに分割しているようです。
ピーターK

0

このPythonスクリプトを試してください。プロセスの生成を必要とせず、ファイルごとに2つのsyscallのみを実行します。Cでの実装は別として、おそらくそれが最速の方法です(すべて777に設定された1500万のファイルのファイルシステムを修正するために必要でした)。

#!/usr/bin/python3
import os
for par, dirs, files in os.walk('.'):
    for d in dirs:
        os.chmod(par + '/' + d, 0o755)
    for f in files:
        os.chmod(par + '/' + f, 0o644)

私の場合、いくつかの特別なファイルのchmoddingが失敗したため、最後のchmodの周りにtry / catchが必要でした。


-1

以下も使用できますtree

tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1"' -- '{}'

フォルダーも表示したい場合は、エコーを追加します

 tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1" && echo$1' -- '{}'

@Scott 1)あなたは正しいです+ x私は755に変更しました; 2)3)「{}」私はこのような単一引用符内のプレースホルダを入れ、これを解決するために
エデュアルドFlorinescu

@Scott私はこれが最良の答えではないことにも同意しますが、遅いのですが、「教訓的な」目的のためにここに残しxargsます。ファイル名に単一引用符自体、私は単一引用符を含むすべてのファイルを列挙し、(引用符は私が意味する)、それらを削除する理由だ多くのコマンドやスクリプトの問題である
エドゥアルトFlorinescu

私は単一引用符を含み、単一引用符を置き換え、すべてのファイルを検索私のシステムでは@Scott
エドゥアルトFlorinescu

@Scott xargsが単一引用符を正しく解決しないという事実をどのように修正しますか?
エデュアルドフロリネスク


-2

例として次のbashスクリプトを使用できます。必ず実行可能権限(755)を付与してください。現在のディレクトリには./autochmod.shを使用するか、別のディレクトリを指定するには./autochmod.sh <dir>を使用します。

#!/bin/bash

if [ -e $1 ]; then
    if [ -d $1 ];then
        dir=$1
    else
        echo "No such directory: $1"
        exit
    fi
else
    dir="./"
fi

for f in $(ls -l $dir | awk '{print $8}'); do
    if [ -d $f ];then
        chmod 755 $f
    else
        chmod 644 $f
    fi
done

2
うわー!非常に多くの問題!(1)$1がnullではないが、ディレクトリの名前ではない(たとえば、タイプミスである)場合、メッセージなしでにdir設定され.ます。(2)である$1必要が"$1"あり$dirます"$dir"。(3)言う必要はありません"./""."は問題ありません(厳密に言えば、ここで引用符は必要ありません)。(4)これは再帰的な解決策ではありません。(5)システムでls -l … | awk '{ print $8 }'、ファイルの変更時間を取得します。ファイル名の最初の単語{ print $9 }を取得する必要あります。そして、それでも(6)これは空白のあるファイル名を処理しません。…
スコット14

1
…そして、最後になりましたが、このスクリプトが現在のディレクトリにある場合(∞)、それchmod 自体は644になり、実行不可能になります!
スコット14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.