파일을 제외한 모든 디렉토리를 재귀 적으로 chmod하는 방법은 무엇입니까?


답변:


802

재귀 적으로 디렉토리에 읽기 및 실행 권한을 부여하려면 다음을 수행하십시오.

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
파일이 너무 많은 디렉토리의 경우 처음 두 예제는 실패합니다 -bash: /bin/chmod: Argument list too long. 마지막 명령은 많은 파일에서 작동하지만 파일을 사용할 때는 sudochmod 대신 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 ...)이름에 공백이있는 파일 이름은 실패합니다.
Dan Dascalescu

7
파일 이름과 파일 수에서 공백과 기호와 관련하여 가장 정확한 (그러나 가장 빠르지는 않은) 버전은 find /path/to/base/dir -type d -exec chmod 755 {} \;( find /path/to/base/dir -type f -exec chmod 644 {} \;)이라고 생각합니다.
피터 K

이것은 읽을 수있는 첫 번째 레이어에만 적용됩니다. 디렉토리 트리에 더 깊이 들어가려면 여러 번 실행해야합니다.
Henk Poley

289

이러한 종류의 일반적인 원인은 디렉토리를 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 = 그룹 및 다른 사람들이 읽고 실행할 수 있습니다. go-w = 그룹과 다른 사람들이 글을 쓸 수 없음
släcker

23
이 패턴은 옵션이 파일의 기존 실행 비트를 재설정하지 않기 chmod -R 777때문에 누군가가 한 상황을 수정 +X하지 않습니다. -x를 사용하면 디렉토리가 재설정되고 디렉토리로 내려 가지 않습니다.
Andrew Vit

3
@ ring0 : 나는 문자 그대로 제기 된 질문에 대답하려고하지 않습니다 .nik은 이미 완벽하게 잘했습니다. 가장 일반적인 경우에 대한 저렴한 솔루션을 지적하고 있습니다. 그리고 예, X주석에서 설명한 것처럼 파일과 디렉토리에 대한 다른 권한을 갖습니다.
bobince

6
go+rX,go-w-> go=rX그렇지 않습니까?
Pierre de LESPINAY

5
chmod u-x,u+X등을 조합 하여 사용 하여 파일의 실행 비트를 제거 할 수 있지만 디렉토리에는 추가 할 수 있습니다.
w0rp

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충분 하다고 생각합니다 .
Scott

나는 이것이 제대로 작동한다는 것을 알았다. 디렉토리를 입력하는 데 문제가 없었습니다
누군가 어딘가

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의 답변 다운 그레이드 입니다 . Nik의 답변에 문제가 있다고 생각하는 이유는 무엇입니까?
Scott

@Scott, nik의 대답은 많은 수의 파일로 (전달) 실패합니다.
Peter K

당신이 착각했다고 99 % 확신합니다. 귀하의 주장을 뒷받침 할 증거를 제공 할 수 있습니까?
Scott

그렇습니다. 실제로 잘못되었습니다. 찾기 ... + 줄을 여러 명령으로 나누는 것 같습니다.
피터 K

0

이 파이썬 스크립트를 사용해보십시오. 프로세스를 생성 할 필요가 없으며 파일 당 두 개의 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)이 문제를 해결하기 위해 자리 표시자를 '{}'과 같이 작은 따옴표로
묶었습니다

@Scott 나는 이것이 최선의 대답은 아니지만 느리다는 데 동의하지만 "학습 적"목적을 위해 여기에 남겨두고 의견도 더 설명하고 사람들은 xargs문제에 대해 배울 수 있습니다. 파일 이름에 따옴표 자체 내가 작은 따옴표를 포함하는 모든 파일을 나열하고이를 제거 왜 많은 명령 및 스크립트에 대한 문제 (따옴표가 내 말)입니다
에드워드 Florinescu

@Scott 내 시스템에서 작은 따옴표가 포함 된 모든 파일을 검색하고 작은 따옴표를 대체했습니다
Eduard Florinescu

@Scott xargs가 작은 따옴표를 올바르게 해결하지 못한다는 사실을 어떻게 고치겠습니까?
Eduard Florinescu


-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) $1null이 아니지만 디렉토리 이름이 아닌 경우 (예 : 오타), 메시지없이 dir설정됩니다 .. (2) $1이어야 "$1"하고 $dir있어야한다 "$dir". (3) 말할 필요가 없습니다 "./". "."괜찮습니다 (엄밀히 말하면 따옴표가 필요하지 않습니다). (4) 이것은 재귀 솔루션이 아닙니다. (5) 내 시스템 ls -l … | awk '{ print $8 }'에서 파일의 수정 시간을 얻습니다. 당신이 필요로 { print $9 }얻을 의 첫 단어 파일 이름을. 그리고 (6) 이것은 공백이있는 파일 이름을 처리하지 않습니다. ...
스콧

1
… 그리고이 스크립트가 현재 디렉토리에있는 경우 마지막으로 (∞) 스크립트 chmod 자체 가 644가되어 실행할 수 없게됩니다!
Scott
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.