SSD Nodes Learn 🎉 VPS $5.50/माह से
गाइड Matt Connorलेखक: Matt Connor

chmod 755 बनाम u+x: Linux permissions का सही तरीका

Linux में chmod 755 और u+x के बीच का अंतर जानें। octal digits और symbolic mode का उपयोग कैसे करें, recursive mode में होने वाली गलतियों से कैसे बचें और capital X का महत्व समझें।

chmod क्या बदलता है

chmod chmod किसी file या directory पर permission bits को बदलता है, और यह उन bits को दो में से एक notation में स्वीकार करता है। Numeric form एक octal number है जो एक ही बार में हर permission bit को बदल देता है। Symbolic form उपयोगकर्ता के एक वर्ग और एक operator का नाम लेती है, और यह केवल उन्हीं bits को संपादित करती है जिनका आप उल्लेख करते हैं। दोनों एक ही system call पर समाप्त होते हैं। अंतर केवल इस बात का है कि जिन bits का आपने उल्लेख नहीं किया है, उनका क्या होता है।

Mode को पढ़ना और mode को बदलना अलग-अलग कार्य हैं। यदि long listing में अक्षर अभी तक स्पष्ट नहीं हैं, तो पहले drwxr-xr-x का क्षेत्र-दर-क्षेत्र अर्थ क्या है पढ़ें। यह मार्गदर्शिका केवल उन्हें बदलने के बारे में है।

यहाँ सब कुछ अपने सामान्य login उपयोगकर्ता के रूप में चलाएँ। root account इन जाँचों को बायपास कर देता है, इसलिए root के रूप में किया गया permission प्रदर्शन कुछ भी साबित नहीं करता है। यदि आप अभी भी एक नए सर्वर पर root के रूप में काम कर रहे हैं, तो न्यूनतम विशेषाधिकार वाला एक सामान्य उपयोगकर्ता बनाएँ और वापस आएँ।

एक ऐसा सैंडबॉक्स सेट करें जिसे आप हटा सकें

cd "$(mktemp -d)"
touch notes.txt

mktemp -d, /tmp के अंतर्गत एक खाली डायरेक्टरी बनाता है और बनाए गए पाथ को प्रिंट करता है, और कमांड सब्स्टीट्यूशन उस पाथ को सीधे cd को पास कर देता है। नीचे दी गई कोई भी चीज़ आपकी किसी महत्वपूर्ण फाइल को प्रभावित नहीं करती है।

एक कमांड हर बदलाव का परिणाम रिपोर्ट करती है:

stat -c '%a %A %n' notes.txt

%a मोड को ऑक्टल नंबर के रूप में प्रिंट करता है, %A उसी मोड को उस लेटर फॉर्मेट में प्रिंट करता है जिसका उपयोग लॉन्ग लिस्टिंग में किया जाता है, और %n नाम को प्रिंट करता है। नीचे दिए गए ब्लॉक्स में, $ से शुरू होने वाली लाइन वह है जिसे आप टाइप करते हैं, और उसके नीचे वाली लाइन वह है जिसे कमांड ने प्रिंट किया है। इन्हें स्वयं चलाएं। आपकी मशीन पर आउटपुट लाइन-दर-लाइन मेल खाना चाहिए, क्योंकि न्यूमेरिक मोड आपके एनवायरनमेंट में किसी भी चीज़ पर निर्भर नहीं करता है।

संख्यात्मक रूप: प्रति वर्ग एक अष्टक (octal) अंक

पहला अंक फ़ाइल के स्वामी (owner) का होता है। दूसरा अंक फ़ाइल के समूह (group) का होता है। तीसरा अंक बाकी सभी के लिए होता है। प्रत्येक अंक एक योग है, जिसमें प्रति बिट एक मान होता है। एक बार में एक बिट सेट करें और देखें कि stat क्या रिपोर्ट करता है।

$ chmod 400 notes.txt
$ stat -c '%a %A %n' notes.txt
400 -r-------- notes.txt
$ chmod 200 notes.txt
$ stat -c '%a %A %n' notes.txt
200 --w------- notes.txt
$ chmod 100 notes.txt
$ stat -c '%a %A %n' notes.txt
100 ---x------ notes.txt

अक्षर अंकों के साथ मेल खाते हैं। अग्रणी फ़ाइल-प्रकार वर्ण के बाद, तीन अक्षरों का पहला समूह स्वामी का है, अगले तीन समूह के हैं, और अंतिम तीन बाकी सभी के हैं। एक वर्ग के भीतर बिट्स को संयोजित करने के लिए मानों को जोड़ें।

$ chmod 600 notes.txt
$ stat -c '%a %A %n' notes.txt
600 -rw------- notes.txt
$ chmod 700 notes.txt
$ stat -c '%a %A %n' notes.txt
700 -rwx------ notes.txt
$ chmod 750 notes.txt
$ stat -c '%a %A %n' notes.txt
750 -rwxr-x--- notes.txt

संख्यात्मक मोड निरपेक्ष (absolute) होता है। यह हर बार चलने पर सभी नौ बिट्स को लिखता है, इसलिए जिस वर्ग के बारे में आपने कभी नहीं सोचा था, वह भी लिखा जाता है।

$ chmod 755 notes.txt
$ stat -c '%a %A %n' notes.txt
755 -rwxr-xr-x notes.txt
$ chmod 600 notes.txt
$ stat -c '%a %A %n' notes.txt
600 -rw------- notes.txt

दूसरे कमांड ने समूह या बाकी सभी के बारे में कुछ नहीं कहा, और उनके बिट्स फिर भी बदल गए। यह संख्यात्मक रूप की विशेषता है, और यही कारण है कि छोटे बदलाव के लिए संख्यात्मक रूप गलत उपकरण है। (chmod setuid, setgid और sticky बिट्स को भी संभालता है, जो इनसे पहले चौथे अंक में रहते हैं। यह एक अलग विषय है, और यह गाइड केवल तीन अंकों तक ही सीमित है।)

सिम्बॉलिक फॉर्म: एक क्लास, एक ऑपरेटर, फिर बिट्स

सबसे पहले क्लास लिखें। u ओनर है, g ग्रुप है, o बाकी सभी हैं, और a एक साथ ये सभी हैं। फिर ऑपरेटर: + बिट्स जोड़ता है, - बिट्स हटाता है, और = उस क्लास को ठीक उन बिट्स पर सेट करता है जिन्हें आप सूचीबद्ध करते हैं और बाकी बिट्स को क्लियर कर देता है। फिर स्वयं बिट्स, जैसे r, w या x

$ chmod 640 notes.txt
$ stat -c '%a %A %n' notes.txt
640 -rw-r----- notes.txt
$ chmod u+x notes.txt
$ stat -c '%a %A %n' notes.txt
740 -rwxr----- notes.txt
$ chmod g-r notes.txt
$ stat -c '%a %A %n' notes.txt
700 -rwx------ notes.txt
$ chmod o=r notes.txt
$ stat -c '%a %A %n' notes.txt
704 -rwx---r-- notes.txt

प्रत्येक कमांड ने एक क्लास को प्रभावित किया और बाकी को वैसा ही छोड़ दिया। क्लॉज को बिना किसी स्पेस के कॉमा से जोड़ें, और chmod उन्हें बाएं से दाएं लागू करता है।

$ chmod u=rw,go=r notes.txt
$ stat -c '%a %A %n' notes.txt
644 -rw-r--r-- notes.txt
$ chmod go= notes.txt
$ stat -c '%a %A %n' notes.txt
600 -rw------- notes.txt

go= जिसके बराबर के निशान के बाद कुछ न हो, वह ग्रुप और बाकी सभी से हर बिट हटा देता है। यह वह स्थिति है जो आप उस फाइल पर चाहते हैं जिसे केवल उसका ओनर ही पढ़ सके, जैसे कि SSH key pair का प्राइवेट हिस्सा।

chmod अपने काम की रिपोर्ट भी दे सकता है, जो किसी स्क्रिप्ट के अंदर महत्वपूर्ण होता है जहाँ स्क्रीन पर कोई नहीं देख रहा होता।

chmod -v u+x notes.txt
chmod -v u+x notes.txt

-v उसे दी गई प्रत्येक फाइल के लिए एक लाइन प्रिंट करता है। दोनों कमांड चलाएं और अपनी स्क्रीन पर दोनों लाइनों की तुलना करें: पहली फाइल का नाम बताती है और उस मोड की रिपोर्ट करती है जिससे वह बदला गया और जिस मोड में वह बदला गया, और दूसरी मोड को यथावत रिपोर्ट करती है, क्योंकि जिस बिट को जोड़ने के लिए कहा गया था वह पहले से ही सेट था। -c केवल तभी एक लाइन प्रिंट करता है जब कोई फाइल वास्तव में बदलती है, इसलिए लॉग में रखने के लिए यह बेहतर विकल्प है।

chmod 755 बनाम u+x: किस नोटेशन का उपयोग करें

एक ही फाइल से शुरुआत करें और तुलना करें कि प्रत्येक नोटेशन क्या परिणाम देता है।

$ chmod 640 notes.txt
$ chmod 755 notes.txt
$ stat -c '%a %A %n' notes.txt
755 -rwxr-xr-x notes.txt
$ chmod 640 notes.txt
$ chmod u+x notes.txt
$ stat -c '%a %A %n' notes.txt
740 -rwxr----- notes.txt

दोनों commands ने फाइल को उसके owner के लिए executable बना दिया। केवल एक ने बाकी दो classes को वैसा ही रहने दिया जैसा वे पहले थीं। जब आप सटीक अंतिम स्थिति जानते हैं और उसे लागू करना चाहते हैं, तो numeric mode का उपयोग करें। यह deployment script के लिए सही है, जिसे ऐसी मशीन पर समान परिणाम देना होता है जिसे आपने पहले कभी नहीं देखा है। जब आपके मन में add (जोड़ना) या remove (हटाना) जैसे शब्द हों, तो symbolic mode का उपयोग करें, क्योंकि numeric form में किसी हिस्से को वैसे ही छोड़ने का कोई तरीका नहीं है।

किसी नई फाइल का mode chmod से तय नहीं होता है। यह उस process के umask से आता है जिसने फाइल बनाई है। अपने shell में umask और umask -S चलाकर देखें कि वहां कौन सा मान प्रभावी है। यह अलग-अलग distributions, आपके login shell और systemd service के बीच, तथा एक account और दूसरे account के बीच भिन्न हो सकता है। umask हर नई फाइल का mode निर्धारित करता है, इसलिए chmod चलने से पहले यह तय करता है कि आप किस स्थिति से शुरुआत कर रहे हैं।

Directory पर execute bit क्या करता है

यह वह गलतफहमी है जिसमें सबसे अधिक समय बर्बाद होता है। एक सामान्य file पर, execute bit का अर्थ है कि kernel उस file को चला सकता है। Directory में कोई निर्देश नहीं होते, इसलिए इसमें चलाने के लिए कुछ भी नहीं है। Directory पर execute bit का अर्थ है traversal: इसके अंदर किसी नाम को resolve करने की अनुमति। dir/file तक पहुँचने के लिए आपको dir पर इसकी आवश्यकता होती है। Read bit एक अलग अनुमति है, और यह directory में मौजूद नामों की सूची देखने की अनुमति देता है। आप एक के बिना दूसरा रख सकते हैं, जिस पर विश्वास करना तब आसान हो जाता है जब आप इसे होते हुए देख लेते हैं।

$ mkdir vault
$ printf 'hello\n' > vault/secret.txt
$ chmod 600 vault/secret.txt
$ chmod 100 vault
$ echo vault/*
vault/*
$ cat vault/secret.txt
hello

Shell ने pattern को बिना बदले print कर दिया क्योंकि vault/* को expand करने का अर्थ है directory को पढ़ना, और जो glob किसी से मेल नहीं खाता उसे error देने के बजाय literal text के रूप में pass कर दिया जाता है। cat ने फिर भी काम किया क्योंकि आपने नाम स्वयं दिया था और traversal की अनुमति थी। अब दोनों bits को आपस में बदलें।

$ chmod 400 vault
$ echo vault/*
vault/secret.txt
$ cat vault/secret.txt
cat: vault/secret.txt: Permission denied

नाम दिखाई दे रहे हैं और contents नहीं। Read आपको सूची देता है। Execute आपको अंदर जाने का रास्ता देता है। आपके द्वारा उपयोग की जाने वाली लगभग हर directory को दोनों की आवश्यकता होती है।

$ chmod 500 vault
$ cat vault/secret.txt
hello

क्यों chmod -R का उपयोग numeric mode के साथ पूरी tree को नुकसान पहुँचाता है

-R पूरी tree को scan करता है और आपके द्वारा दिए गए mode को हर उस चीज़ पर लागू कर देता है जो उसे मिलती है। एक directory और एक data file को अलग-अलग bits की आवश्यकता होती है, इसलिए एक ही absolute number दोनों के लिए सही नहीं हो सकता। एक छोटी tree बनाएँ और देखें कि यह कैसे गलत हो जाता है।

$ mkdir -p site/css
$ touch site/index.html site/css/main.css
$ printf '#!/bin/bash\necho hi\n' > site/deploy.sh
$ chmod 755 site site/css site/deploy.sh
$ chmod 644 site/index.html site/css/main.css
$ stat -c '%a %A %n' site site/css site/index.html site/css/main.css site/deploy.sh
755 drwxr-xr-x site
755 drwxr-xr-x site/css
644 -rw-r--r-- site/index.html
644 -rw-r--r-- site/css/main.css
755 -rwxr-xr-x site/deploy.sh

यह वह layout है जो static files की एक directory को चाहिए होता है। यहाँ पहली recursive गलती है।

$ chmod -R 755 site
$ stat -c '%a %A %n' site/index.html site/css/main.css
755 -rwxr-xr-x site/index.html
755 -rwxr-xr-x site/css/main.css

कुछ भी नहीं टूटा, और यही समस्या है। यह गलती silent है, इसलिए यह वर्षों तक copy किए गए निर्देशों में बनी रहती है। data की दो files अब program होने का दावा करती हैं। Git execute bit को store करता है, इसलिए आपका अगला commit इस बदलाव को हर उस व्यक्ति तक पहुँचाता है जो repository को clone करता है, और rsync तथा tar इसे हर उस machine तक ले जाते हैं जहाँ आप tree को copy करते हैं।

दूसरी recursive गलती loud है। बिना execute bit वाले mode को किसी directory पर लागू करें और directory बंद हो जाएगी।

$ chmod 644 site
$ stat -c '%a %A %n' site
644 drw-r--r-- site
$ echo site/*
site/css site/deploy.sh site/index.html
$ cd site
bash: cd: site: Permission denied
$ cat site/index.html
cat: site/index.html: Permission denied

names अभी भी listed हैं क्योंकि read bit बच गया है, लेकिन directory के माध्यम से हर path बंद हो गया है क्योंकि execute bit नहीं बचा। chmod -R 644 site एक ही command में tree की हर directory के साथ ऐसा करता है। उसके बाद आपको जो मिलता है वह हमेशा एक समान नहीं होता, क्योंकि chmod को उन्हीं directories से गुजरना पड़ता है जिनका traversal वह छीन रहा है, इसलिए यह मानने के बजाय कि सब ठीक है, find site -type d -exec stat -c '%a %n' {} + के साथ जाँचें कि वास्तव में क्या लागू हुआ है। आगे बढ़ने से पहले इसे ठीक करें।

$ chmod 755 site
$ chmod 644 site/index.html site/css/main.css
$ stat -c '%a %A %n' site site/index.html
755 drwxr-xr-x site
644 -rw-r--r-- site/index.html

recursive chmod का कोई undo नहीं होता। chmod यह record नहीं करता कि उसने क्या replace किया है, इसलिए repair आपको ही करनी पड़ती है, यह मानते हुए कि modes पहले क्या थे। यह accidental rm -rf के बाद files को reconstruct करने जैसा ही धीमा और अनिश्चित काम है, और सबक वही है: enter दबाने से पहले recursive command के target की जाँच करें।

राजधानी X: निर्देशिकाओं पर निष्पादित करें, न कि हर फ़ाइल पर

Symbolic modes X के साथ-साथ x को भी स्वीकार करते हैं। X execute bit को केवल वहीं सेट करता है जहाँ इसका अर्थ हो: किसी निर्देशिका (directory) पर, या किसी ऐसी नियमित फ़ाइल पर जिसमें पहले से ही किसी वर्ग (class) के लिए execute bit मौजूद हो। यह नियम बिल्कुल वही है जिसका आप चाहते थे कि -R पालन करे।

$ chmod -R u=rwX,go=rX site
$ stat -c '%a %A %n' site site/css site/index.html site/css/main.css site/deploy.sh
755 drwxr-xr-x site
755 drwxr-xr-x site/css
644 -rw-r--r-- site/index.html
644 -rw-r--r-- site/css/main.css
755 -rwxr-xr-x site/deploy.sh

एक कमांड, और निर्देशिकाएं traversable बनी रहीं जबकि डेटा फ़ाइलें अपरिवर्तित रहीं। स्क्रिप्ट ने अपना execute bit बनाए रखा क्योंकि इसमें पहले से ही एक था, जो X नियम का दूसरा भाग है। X फ़ाइल के वर्तमान मोड को पढ़ता है, इसलिए जिस फ़ाइल ने अपना हर execute bit खो दिया है, उसे इसके द्वारा वापस नहीं लाया जा सकता।

$ chmod 644 site/deploy.sh
$ chmod -R u=rwX,go=rX site
$ stat -c '%a %A %n' site/deploy.sh
644 -rw-r--r-- site/deploy.sh
$ site/deploy.sh
bash: site/deploy.sh: Permission denied
$ chmod u+x site/deploy.sh
$ stat -c '%a %A %n' site/deploy.sh
744 -rwxr--r-- site/deploy.sh
$ site/deploy.sh
hi

यही नियम दूसरी दिशा में भी काम करता है। X किसी फ़ाइल के मौजूदा execute bit को किसी अन्य वर्ग तक विस्तारित कर देगा:

$ chmod go+X site/deploy.sh
$ stat -c '%a %A %n' site/deploy.sh
755 -rwxr-xr-x site/deploy.sh

अतः लोअरकेस x एक नामित फ़ाइल के लिए है जिसे आप चलाने योग्य बनाना चाहते हैं, और X पूरे ट्री (tree) पर लागू करने के लिए है। जब आप वर्तमान मोड पर आधारित नियम के बजाय प्रत्येक प्रकार की चीज़ के लिए एक सटीक मोड चाहते हैं, तो इसके बजाय find के साथ वॉक (walk) को विभाजित करें।

find site -type d -exec chmod 755 {} +
find site -type f -exec chmod 644 {} +
chmod u+x site/deploy.sh

-type d निर्देशिकाओं का चयन करता है और -type f नियमित फ़ाइलों का चयन करता है, इसलिए प्रत्येक प्रकार को वह मोड मिलता है जो उसे मिलना चाहिए। -exec ... + प्रति फ़ाइल एक प्रक्रिया शुरू करने के बजाय कई पथों (paths) को एक chmod कॉल में बैच करता है, जो हजारों प्रविष्टियों वाले ट्री पर महत्वपूर्ण होता है। स्क्रिप्ट को अपना बिट एक अलग लाइन पर, जानबूझकर वापस मिलता है।

Check the result before you walk away

Two commands find the mistakes that matter after any recursive change. The first lists directories you can no longer walk into.

find . -type d ! -perm -u+x

The second lists files that any account on the machine may edit.

find . -type f -perm -o+w

In -perm -o+w, the leading - means at least these bits, so it matches a file whose o class holds the write bit whatever else is set. Neither command printing anything is the result you want. Run both from the top of any tree you have just changed with -R, and run stat -c '%a %A %n' on the handful of paths you meant to change, so the mode you believe you set is the mode the kernel actually holds.

FAQ

chmod 755 और chmod u+x में क्या अंतर है?

Numeric mode पूर्ण (absolute) होता है। यह फाइल पर हर permission bit को लिख देता है, इसलिए जिन classes के बारे में आपने नहीं सोचा, वे भी बदल जाती हैं। Symbolic mode एक संपादन (edit) है। u+x केवल owner के लिए एक bit जोड़ता है और बाकी सभी bits को वैसा ही रहने देता है। जब आप फाइल की सटीक अंतिम स्थिति जानते हों, तो numeric form का उपयोग करें। जब आप केवल एक चीज जोड़ना या हटाना चाहते हों, तो symbolic form का उपयोग करें। किसी भी command को चलाने से पहले और बाद में stat -c '%a %A %n' <file> चलाएं, इससे output में अंतर स्पष्ट हो जाएगा।

वेब फाइलों की डायरेक्टरी पर chmod -R 755 का उपयोग करना गलत क्यों है?

क्योंकि -R डायरेक्टरी और सामान्य फाइलों दोनों पर एक ही absolute mode लागू कर देता है, जबकि इन दोनों को अलग-अलग bits की आवश्यकता होती है। डायरेक्टरी को traversable होने के लिए execute bit की आवश्यकता होती है। HTML और CSS जैसी डेटा फाइलों को इसकी आवश्यकता नहीं होती है, और उन्हें executable के रूप में मार्क करना एक ऐसा बदलाव है जिसे git आपके अगले commit में रिकॉर्ड कर लेता है और rsync अगली मशीन पर कॉपी कर देता है। chmod -R u=rwX,go=rX <dir> का उपयोग करें ताकि execute bit केवल डायरेक्टरी पर ही लागू हो, या फिर -type d और -type f के साथ find का उपयोग करें ताकि प्रत्येक प्रकार को उसका उचित mode मिल सके।

डायरेक्टरी पर execute bit क्या करता है?

यह traversal (आवागमन) की अनुमति देता है, execution की नहीं। डायरेक्टरी के अंदर चलाने के लिए कुछ भी नहीं होता है। Execute bit का अर्थ है उसके अंदर किसी नाम को resolve करने की अनुमति, इसलिए किसी फाइल को खोलने से पहले आपको उस फाइल तक के रास्ते में आने वाली हर डायरेक्टरी पर इसकी आवश्यकता होती है। Read bit अलग है और यह नामों की सूची देखने की अनुमति देता है। आप एक को दूसरे के बिना रख सकते हैं: केवल execute के साथ आप उस फाइल को खोल सकते हैं जिसका नाम आप पहले से जानते हैं, जबकि shell उस डायरेक्टरी में glob का विस्तार नहीं कर पाएगा; और केवल read के साथ आप नाम देख सकते हैं, लेकिन उन्हें खोलने का हर प्रयास विफल हो जाएगा।

मुझे lowercase x के बजाय capital X का उपयोग कब करना चाहिए?

जब भी command recursive हो, X का उपयोग करें। X डायरेक्टरी पर execute bit सेट करता है, और सामान्य फाइलों पर केवल तभी जब एक execute bit पहले से सेट हो। इस प्रकार, एक ही बार में पूरी tree traversable हो जाती है और डेटा फाइलें प्रोग्राम में नहीं बदलतीं। जब आप किसी एक फाइल को इंगित कर रहे हों और आपका मतलब केवल उसी फाइल से हो, तो lowercase x का उपयोग करें। एक सीमा याद रखने योग्य है: X उस execute bit को बहाल नहीं कर सकता जिसे पहले ही फाइल से पूरी तरह हटा दिया गया हो, क्योंकि उसके पास मिलान करने के लिए कुछ नहीं बचता। उसे chmod u+x <file> के साथ वापस सेट करें।

क्या chmod फाइल का मालिक बदलता है?

नहीं। chmod केवल permission bits को बदलता है। स्वामित्व chown (user के लिए) और chgrp (group के लिए) के पास होता है, और किसी फाइल को दूसरे user को सौंपने के लिए root की आवश्यकता होती है। यह महत्वपूर्ण है क्योंकि bits को फाइल पर दर्ज owner और group के आधार पर पढ़ा जाता है, न कि उस व्यक्ति के आधार पर जिसने इसे आखिरी बार लिखा था। यह तय करने से पहले कि आपको वास्तव में तीनों में से किस command की आवश्यकता है, owner, group और mode को एक साथ देखने के लिए stat -c '%U %G %a %n' <file> चलाएं।