Dosyalar dışında tüm dizinleri yinelemeli olarak chmod nasıl yapılır?


Yanıtlar:


801

Dizinleri tekrar tekrar vermek için ayrıcalıkları okuyun ve uygulayın:

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

Tekrar tekrar dosya okuma ayrıcalıkları vermek için :

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

Veya, işlenecek çok sayıda nesne varsa:

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

Veya chmodyumurtlamayı azaltmak için :

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
İlk iki örnek çok fazla dosyalarla dizinleri için başarısız: -bash: /bin/chmod: Argument list too long. Son komut birçok sudofind /path/to/base/dir -type d -print0 | sudo xargs -0 chmod 755
dosyayla

2
Ayrıca bu komutlar vardır nota dahil taban dir. Yani yukarıdaki örnekte, dirayrıca 755'e ayarlanır
CenterOrbit

2
chmod ... $(find /path/to/base/dir -type ...)adında boşluk olan dosya adları için başarısız olur.
Dan Dascalescu

7
Dosya adlarındaki ve dosya sayısındaki boşluklara ve sembollere göre en doğru (ancak en hızlı olmayan) sürümün find /path/to/base/dir -type d -exec chmod 755 {} \;( find /path/to/base/dir -type f -exec chmod 644 {} \;) olduğunu düşünüyorum.
Peter K,

Bunun yalnızca okuyabileceği ilk katmana gittiğini unutmayın. Dizin ağacının derinliklerine inmek için birkaç kez çalıştırmanız gerekecektir.
Henk Poley

290

Bu tür bir şey için ortak bir neden, dizinleri 755'e ayarlamak ama dosyaları 644'e ayarlamaktır. Bu durumda, nik'in örneğinden biraz daha hızlı bir yol var find:

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

Anlamı:

  • -R = özyinelemeli;
  • u+rwX = Kullanıcılar okuyabilir, yazabilir ve uygulayabilir;
  • go+rX = grup ve diğerleri okuyabilir ve yürütebilir;
  • go-w = grup ve diğerleri yazamıyor

Burada dikkat edilmesi gereken en önemli şey, büyük harflerin Xküçük harfe farklı davranmalarıdır x. Manuel olarak okuyabiliriz:

Dosya bir dizinse veya çalıştırma / arama bitlerinden herhangi biri orijinal (değiştirilmemiş) modda ayarlanmışsa, execute / search bit.

Başka bir deyişle, bir dosyadaki chmod u + X yürütme bitini ayarlamaz; ve g + X yalnızca kullanıcı için ayarlanmışsa ayarlayacaktır.


5
-R = özyinelemeli; u + rwX = Kullanıcılar okuyabilir, yazabilir ve uygulayabilir; go + rX = grup ve diğerleri okuyabilir ve yürütebilir; go-w = grup ve diğerleri yazamıyor
släcker

23
Bu kalıp, birisinin yapması durumunda durumu düzeltmeyecektir, chmod -R 777çünkü +Xseçenek dosyalar üzerindeki mevcut çalıştırma bitlerini sıfırlayamaz. -X kullanmak dizinleri sıfırlar ve içine düşmeyi önler.
Andrew Vit,

3
@ ring0: Soruyu tam olarak söylendiği gibi cevaplamak istemiyorum - nik zaten bunu çok iyi yaptı. En yaygın durum için daha ucuz bir çözümü işaret ediyorum. Ve evet, Xyorumlarda açıklandığı gibi, dosyalar ve dizinler için farklı izinler alırsınız .
bobince

6
go+rX,go-w-> go=rXdeğil mi?
Pierre de LESPINAY

5
chmod u-x,u+XDosyaların yürütme bitlerini kaldırmak, ancak dizinler için bunları eklemek için, vb. Bir arada da kullanabilirsiniz .
w0rp

14

Dosyaların 644 olarak ayarlandığından ve yürütme bayrağının bulunduğu yolda dosyalar bulunduğundan emin olmak için, önce yürütme bayrağını kaldırmanız gerekir. + X yürütme bayrağını zaten sahip olan dosyalardan kaldırmaz.

Örnek:

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

Güncelleme: ilk değişiklik (ugo-x) dizini beklenilemez hale getirdiğinden başarısız oldu, bu yüzden altındaki tüm dosyalar değişmedi.


1
Bu benim için çalışıyor ve neden olmadığını anlamadım. (Tabii ki, sadece yaptıysanız chmod -R ugo-x path, bu bir sorun olabilir. Fakat tam komut chmod u+rwXher dizinde içine girmeden önce bunu yapacaktır.) Ancak chmod R u=rw,go=r,a+X pathbunun yeterli olduğuna inanıyorum - ve daha kısa.
Scott

Bunun düzgün çalıştığını gördüm; dizin girme ile ilgili herhangi bir sorun yoktu
Birisi Başka Bir Yerde

4

Bunun için küçük bir senaryo yazmaya karar verdim.

Diziler ve / veya dosyalar için özyinelemeli chmod betiği - 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

Temelde özyinelemeli chmod yapar, ancak komut satırı seçenekleri için biraz esneklik sağlar (dizin ve / veya dosya izinlerini ayarlar veya her ikisini de otomatik olarak her şeyi 755-644'e sıfırlar). Ayrıca birkaç hata senaryosunu da kontrol eder.

Ben de bu konuda yazdığı blogumda .


2

Dizinleri tekrar tekrar vermek için ayrıcalıkları okuyun ve uygulayın:

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

Tekrar tekrar dosya okuma ayrıcalıkları vermek için :

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

Nik'in cevabını doğruluk tarafında yükseltmeme izin vermemekten daha iyidir. Çözümüm daha yavaş, ancak dosya adlarındaki herhangi bir sembolle, herhangi bir sayıda dosyayla çalışıyor ve sudo ile normal şekilde çalıştırabilirsiniz (ancak sudo ile farklı dosyalar bulabildiğine dikkat edin).


Bu bir düşürme ait Nik'ın cevap . Neden nik'in cevabında yanlış bir şey olduğuna inanıyorsun?
Scott

@Scott, nik'in cevabı (vey) çok sayıda dosyayla başarısız oldu.
Peter K

Yanıldığına% 99 eminim. Talebinizi desteklemek için herhangi bir kanıt sunabilir misiniz?
Scott

Evet, görünüşe göre gerçekten hatalıyım. Bulmak ... + çizgiyi birden fazla komuta bölmek gibi görünüyor, güzel yakalama!
Peter K

0

Bu python betiğini deneyin; işlemlerin yumurtlamasını gerektirmez ve dosya başına sadece iki çağrı yapar. C'deki bir uygulama dışında, muhtemelen bunu yapmanın en hızlı yolu olacaktır (hepsi 777 olarak ayarlanmış 15 milyon dosyalık bir dosya sistemini düzeltmek için ihtiyacım vardı)

#!/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)

Benim durumumda, bazı özel dosyaları chmodding başarısız olduğundan, son chmod etrafında bir try / catch gerekliydi.


-1

Ayrıca şunları da kullanabilirsiniz tree:

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

ve ayrıca klasörü görüntülemek isterseniz bir yankı ekleyin.

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

@Scott 1) ​​+ x konusunda haklısın 755 olarak değiştirdim; 2) 3) bunu çözmek için yer tutucuyu '{}' gibi tek bir teklife koydum
Eduard Florinescu

@Scott, bunun en iyi cevabın aynı olmadığını ve aynı zamanda “didaktik” amaçlar için buradan ayrılacağını ve yorumların daha da açıklanacağını kabul ediyorum xargs. Dosya adlarında Tek tırnak kendileri ben tek tırnak içeren tüm dosyaları listelenir ve bunları kaldırıldı neden çok komut ve komut dosyası için bir sorun (tırnak Yani) vardır
Eduard Florinescu

@Scott Sistemlerimde tek tırnak içeren tüm dosyaları aradım ve tek tırnak işaretleri değiştirdim
Eduard Florinescu 10:18

@Scott xargs'ın tekil alıntıları doğru çözemediği gerçeğini nasıl düzeltirsiniz?
Eduard Florinescu


-2

Aşağıdaki bash betiğini örnek olarak kullanabilirsiniz. Yürütülebilir izinleri verdiğinizden emin olun (755). Geçerli dizin için ./autochmod.sh, farklı bir tane belirtmek için ./autochmod.sh <dir> 'i kullanın.

#!/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
Vaov! Çok fazla sorun var! (1) Eğer $1boş değilse, ancak bir dizinin adı değilse (örneğin bir yazım hatası olur), o dirzaman .mesaj olmadan ayarlanır . (2) $1olmalı "$1"ve $dirolmalı "$dir". (3) Söylemene gerek yok "./"; "."iyidir (ve kesinlikle konuşursak, burada alıntılara ihtiyacın yok). (4) Bu özyinelemeli bir çözüm değildir. (5) Sistemimde, ls -l … | awk '{ print $8 }'dosyaların değişiklik zamanlarını alıyor. İhtiyacınız { print $9 }olsun ilk kelime dosya. Ve o zaman bile, (6) bu, dosya adlarını beyaz boşlukla işlemez. …
Scott

1
… Ve, son fakat en az değil (∞) bu script mevcut dizinde ise, chmod kendisi 644 olacaktır , bu yüzden kendini çalıştırılamaz hale getirecektir !
Scott
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.