फ़ाइलों को छोड़कर सभी निर्देशिकाओं को फिर से कैसे करें?


573

कैसे 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
पहले दो उदाहरण बहुत सी फाइलों के साथ निर्देशिकाओं के लिए असफल होते हैं -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
यह भी ध्यान दें, ये आदेश आधार डायर के समावेशी हैं । तो उपरोक्त उदाहरण में, dir755 पर भी सेट किया जाएगा।
सेंटरऑर्बिट

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 {} \;)।
पीटर के

ध्यान दें कि यह केवल पहली परत पर जाता है जो इसे पढ़ सकता है। डायरेक्ट्री ट्री में गहराई तक जाने के लिए आपको इसे कई बार निष्पादित करना होगा।
हेनक पोली

290

इस तरह की चीज़ों के लिए एक सामान्य कारण 755 में निर्देशिकाओं को सेट करना है, लेकिन फाइलें 644 में हैं। इस मामले में नीक के 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 = recursively; u + rwX = उपयोगकर्ता पढ़ सकते हैं, लिख सकते हैं और निष्पादित कर सकते हैं; go + rX = समूह और अन्य पढ़ और निष्पादित कर सकते हैं; go-w = समूह और अन्य नहीं लिख सकते हैं
släcker

23
यह पैटर्न उस स्थिति को ठीक नहीं करेगा जब किसी ने किया है chmod -R 777क्योंकि +Xविकल्प फ़ाइलों पर मौजूदा निष्पादित बिट्स को रीसेट नहीं करेगा। -X का उपयोग निर्देशिकाओं को रीसेट करेगा, और उनमें उतरने से रोकेगा।
एंड्रयू विटामिन

3
@ ring0: मैं इस प्रश्न का उत्तर देने का इरादा नहीं कर रहा हूं कि जैसा कि posed - nik पहले ही कर चुका है। मैं सबसे सामान्य मामले के लिए एक सस्ता समाधान इंगित कर रहा हूं। और हां, आपको फाइलों और निर्देशिकाओं के लिए अलग-अलग अनुमति मिलती है X, जैसा कि टिप्पणियों में बताया गया है।
1

6
go+rX,go-w-> go=rXहै ना?
पियरे डे लेसपिन

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यह पर्याप्त है - और यह छोटा है।
स्कॉट

मैंने पाया कि यह ठीक से काम कर रहा है; निर्देशिका में प्रवेश करने के साथ कोई समस्या नहीं थी
कोई व्यक्ति

4

मैंने खुद इसके लिए थोड़ी स्क्रिप्ट लिखने का फैसला किया।

डायर और / या फ़ाइलों के लिए पुनरावर्ती chmod स्क्रिप्ट - जिस्ट :

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 {} \;

देर से बेहतर मुझे कभी भी नीक के उत्तर को शुद्धता के पक्ष में अपग्रेड नहीं करने दिया। मेरा समाधान धीमा है, लेकिन यह फ़ाइल नाम में किसी भी प्रतीक के साथ, किसी भी संख्या में फ़ाइलों के साथ काम करता है, और आप इसे सामान्य रूप से sudo के साथ चला सकते हैं (लेकिन सावधान रहें कि यह sudo के साथ विभिन्न फ़ाइलों की खोज कर सकता है)।


यह नीक के उत्तर का एक अपग्रेड है । आप क्यों मानते हैं कि नीक के उत्तर में कुछ गलत है?
स्कॉट

@Scott, nik का उत्तर बड़ी संख्या में फाइलों के साथ (vey) विफल रहता है।
पीटर के

मुझे 99% यकीन है कि आप गलत हैं। क्या आप अपने दावे का समर्थन करने के लिए कोई सबूत दे सकते हैं?
स्कॉट

हां, ऐसा लगता है कि मैं वास्तव में गलत हूं। लगता है ... + कई आदेशों में लाइन को तोड़ने के लिए लगता है, अच्छी पकड़!
पीटर के

0

इस अजगर स्क्रिप्ट की कोशिश करो; इसके लिए प्रक्रियाओं की स्पानिंग की आवश्यकता नहीं है और प्रति फ़ाइल केवल दो syscalls करता है। सी में एक कार्यान्वयन के अलावा, यह शायद इसे करने का सबसे तेज़ तरीका होगा (मुझे 15 मिलियन फ़ाइलों की एक फाइल सिस्टम को ठीक करने के लिए इसकी आवश्यकता थी जो सभी 777 पर सेट थे)

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

मेरे मामले में, आखिरी chmod के आसपास एक कोशिश / पकड़ की आवश्यकता थी, क्योंकि कुछ विशेष फ़ाइलों को चकमा देने में विफल रहा।


-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' -- '{}'

@ सेट 1) आप सही हैं + x मैं 755 में बदल गया; 2) 3) इसे हल करने के लिए मैंने इस '{}' जैसे प्लेसहोल्डर को एकल उद्धरण में रखा
Eduard Florinescu

@ सच में मैं मानता हूं कि यह सबसे अच्छा जवाब नहीं है, यह भी धीमी है लेकिन "डिडक्टिक" उद्देश्यों के लिए यहां छोड़ देंगे, टिप्पणियों में आगे भी समझाया जाएगा, लोग xargsमुद्दों के बारे में भी जान सकते हैं। फ़ाइलनाम में एकल उद्धरण स्वयं कई आदेशों और स्क्रिप्ट के लिए एक समस्या है यही कारण है कि मैंने सभी फ़ाइलों को एकल उद्धरणों के साथ सूचीबद्ध किया और उन्हें हटा दिया (उद्धरण मेरा मतलब है)
एडुआर्ड फ्लोरिनेस्कु

@ अपने सिस्टम पर मैंने उन सभी फाइलों की खोज की जिनमें एकल उद्धरण शामिल थे और उन्होंने एकल उद्धरणों को प्रतिस्थापित किया
एडुआर्ड फ्लोरिंसक्यू

@ सही आप इस तथ्य को कैसे ठीक करेंगे कि xargs एकल उद्धरणों को सही ढंग से हल नहीं करता है?
एडुआर्ड फ्लोरिंसक्यू


-2

आप उदाहरण के रूप में निम्नलिखित बैश स्क्रिप्ट का उपयोग कर सकते हैं। इसे निष्पादन योग्य अनुमति (755) अवश्य दें। बस का उपयोग करें। / currentochmod.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अशक्त नहीं है, लेकिन निर्देशिका का नाम नहीं है (जैसे, एक टाइपो है), तो बिना किसी संदेश के dirसेट हो जाता है .। (२) $1होना चाहिए "$1"और $dirहोना चाहिए "$dir"। (३) आपको कहने की आवश्यकता नहीं है "./"; "."ठीक है (और, सख्ती से बोलते हुए, आपको यहां उद्धरणों की आवश्यकता नहीं है)। (४) यह पुनरावर्ती समाधान नहीं है। (५) मेरे सिस्टम में, ls -l … | awk '{ print $8 }'फाइलों का संशोधन समय पर होता है। आपको फ़ाइल नाम का पहला शब्द{ print $9 } प्राप्त करने की आवश्यकता है । और फिर भी, (6) यह सफेद स्थान के साथ फ़ाइल नाम को संभाल नहीं करता है। ...
स्कॉट

1
… और, आखिरी लेकिन कम से कम (not) यदि यह स्क्रिप्ट वर्तमान निर्देशिका में है, तो यह 644 तक chmod ही होगी , इस प्रकार यह स्वयं को गैर-निष्पादन योग्य बना देगा!
स्कॉट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.