Ls -l आउटपुट फॉर्मेट को chmod फॉर्मेट में कन्वर्ट करें


17

कहो कि मेरे पास निम्न आउटपुट है ls -l:

drwxr-xr-x 2 root root 4096 Apr  7 17:21 foo

मैं इसका उपयोग अपने आप प्रारूप में कैसे कर सकता हूं chmod?

उदाहरण के लिए:

$ echo drwxr-xr-x | chmod-format
755

मैं OS X 10.8.3 का उपयोग कर रहा हूं।


2
साथ बहुत आसान है stat। क्या आपके पास है? (यह एक GNU टूल है, इसलिए ज्यादातर लिनक्स पर उपलब्ध है, यूनिक्स पर नहीं।)
मैनटवर्क

@manatwork stat fooदेता है 16777219 377266 drwxr-xr-x 119 Tyilo staff 0 4046 "Apr 7 17:49:03 2013" "Apr 7 18:08:31 2013" "Apr 7 18:08:31 2013" "Nov 25 17:13:52 2012" 4096 0 0 /Users/Tyilo। मैं इसमें नहीं दिख रहा हूं 755
टाइइलो

जवाबों:


24

कुछ सिस्टम में फ़ाइल की अनुमतियों को संख्या के रूप में प्रदर्शित करने की आज्ञा है, लेकिन दुर्भाग्य से, पोर्टेबल कुछ भी नहीं है।

zshमॉड्यूल में एक stat(उर्फ zstat) अंतर्निहित है stat:

zmodload zsh/stat
stat -H s some-file

फिर, modeहै, $s[mode]लेकिन मोड है, वह टाइप + परमिट है।

यदि आप चाहते हैं कि ऑक्टल में व्यक्त की गई अनुमतियाँ, आपको चाहिए:

perms=$(([##8] s[mode] & 8#7777))

BSDs ( Apple OS / X सहित ) के पास भी एक statकमांड है।

mode=$(stat -f %p some-file)
perm=$(printf %o "$((mode & 07777))"

GNU पाते हैं (1990 से और शायद पहले के रूप में) ऑक्टल के रूप में अनुमतियों को प्रिंट कर सकते हैं:

find some-file -prune -printf '%m\n'

बाद में (2001, लंबे समय बाद zsh stat(1997) लेकिन BSD stat(2002) से पहले GNU statकमांड को फिर से एक अलग वाक्यविन्यास के साथ पेश किया गया था:

stat -c %a some-file

उन लोगों से बहुत पहले, IRIX में पहले से ही एक statआदेश था (पहले से ही 1994 में IRIX 5.3 में) एक और वाक्यविन्यास के साथ:

stat -qp some-file

फिर, जब कोई मानक कमांड नहीं है, तो पोर्टेबिलिटी के लिए सबसे अच्छा शर्त उपयोग करना है perl:

perl -e 'printf "%o\n", (stat shift)[2]&07777' some-file

15

आप विकल्प statका उपयोग करके जीएनयू को ऑक्टल प्रारूप में अनुमतियों को आउटपुट करने के लिए कह सकते हैं -c। से man stat:

       -c  --format=FORMAT
              use the specified FORMAT instead of the default; output a
              newline after each use of FORMAT
⋮
       %a     access rights in octal
⋮
       %n     file name

तो आपके मामले में:

bash-4.2$ ls -l foo
-rw-r--r-- 1 manatwork manatwork 0 Apr  7 19:43 foo

bash-4.2$ stat -c '%a' foo
644

या आप इसे statमान्य कमांड के रूप में आउटपुट स्वरूपित करके भी स्वचालित कर सकते हैं :

bash-4.2$ stat -c "chmod %a '%n'" foo
chmod 644 'foo'

bash-4.2$ stat -c "chmod %a '%n'" foo > setpermission.sh

bash-4.2$ chmod a= foo

bash-4.2$ ls -l foo
---------- 1 manatwork manatwork 0 Apr  7 19:43 foo

bash-4.2$ sh setpermission.sh 

bash-4.2$ ls -l foo
-rw-r--r-- 1 manatwork manatwork 0 Apr  7 19:43 foo

वाइल्डकार्ड का उपयोग करने पर उपरोक्त समाधान कई फाइलों के लिए भी काम करेगा:

stat -c "chmod -- %a '%n'" -- *

व्हॉट्सएप कैरेक्टर वाले फाइल नामों के साथ सही तरीके से काम करेंगे, लेकिन सिंगल कोट्स वाले फाइल नामों पर फेल हो जाएंगे।


2
मेरे statपास कोई -cविकल्प नहीं है । मैं OS X 10.8.3 का उपयोग कर रहा हूं।
टिलो

जानकारी के लिए धन्यवाद, @Tyilo। और क्षमा करें, मैं OS X के टूल के साथ मदद नहीं कर सकता।
मैनेटवर्क

मैक ओएस एक्स पर मैनपेज ^ W ^ W ^ W स्टेट (1) पढ़ने की कोशिश करें, आउटपुट फॉर्मेट को निर्दिष्ट करने के लिए -f फ्लैग करें, जैसेstat -f 'chmod %p "%N"'
gelraen

12

प्रतीकात्मक से अष्टक संकेतन में बदलने के लिए, मैं एक बार साथ आया :

chmod_format() {
  sed 's/.\(.........\).*/\1/
    h;y/rwsxtSTlL-/IIIIIOOOOO/;x;s/..\(.\)..\(.\)..\(.\)/|\1\2\3/
    y/sStTlLx-/IIIIIIOO/;G
    s/\n\(.*\)/\1;OOO0OOI1OIO2OII3IOO4IOI5IIO6III7/;:k
    s/|\(...\)\(.*;.*\1\(.\)\)/\3|\2/;tk
    s/^0*\(..*\)|.*/\1/;q'
}

विस्तारित:

#! /bin/sed -f
s/.\(.........\).*/\1/; # extract permissions and discard the rest

h; # store a copy on the hold space

# Now for the 3 lowest octal digits (rwx), translates the flags to
# binary where O means 0 and I means 1.
# l, L are for mandatory locking (a regular file that has 02000 on
# and not 010 on some systems like Linux). Some ls implementations
# like GNU ls confusingly use S there like for directories even though 
# it has nothing to do with setgid in that case. Some ls implementations 
# use L, some others l (against POSIX which requires an uppercase
# flag for extra flags when the execution bit is not set).
y/rwsxtSTlL-/IIIIIOOOOO/

x; # swap hold and pattern space, to do a second processing on those flags.

# now only consider the "xXlLsStT" bits:
s/..\(.\)..\(.\)..\(.\)/|\1\2\3/

y/sStTlLx-/IIIIIIOO/; # make up the 4th octal digit as binary like before

G; # append the hold space so we now have all 4 octal digits as binary

# remove the extra newline and append a translation table
s/\n\(.*\)/\1;OOO0OOI1OIO2OII3IOO4IOI5IIO6III7/

:k
  # translate the OOO -> 0 ... III -> 7 in a loop
  s/|\(...\)\(.*;.*\1\(.\)\)/\3|\2/
tk

# trim leading 0s and our translation table.
s/^0*\(..*\)|.*/\1/;q

यह ls -lएक फाइल के आउटपुट से ऑक्टल नंबर लौटाता है ।

$ echo 'drwSr-sr-T' | chmod_format
7654

मैंने इसका उपयोग dpkg"स्थापित" के रूप में वापस अनुमतियाँ सेट करने के आउटपुट पर किया । बिना अनुमति के शाब्दिक प्रश्न का उत्तर देने के लिए धन्यवाद किस कमांड ने अनुमति स्ट्रिंग का उत्पादन किया।
HiTechHiTouch

3

इस आदेश के तहत मैक पर श

stat -f "%Lp %N" your_files

यदि आप केवल संख्यात्मक अनुमति चाहते हैं, तो% Lp का ही उपयोग करें।

उदाहरण के लिए:

stat -f "%Lp %N" ~/Desktop
700 Desktop

700 सांख्यिक अनुमति है जिसे chmod में उपयोग किया जा सकता है, और डेस्कटॉप फ़ाइल नाम है।


2

यहाँ प्रश्न का उत्तर है Y (अनदेखी सवाल एक्स ), ओ पी के प्रयास से प्रेरित:

#!/bin/bash
LC_COLLATE=C
while read ls_out
do
        extra=0
        perms=0
        for i in {1..9}
        do
                # Shift $perms to the left one bit, so we can always just add the LSB.
                let $((perms*=2))
                this_char=${ls_out:i:1}
                # If it's different from its upper case equivalent,
                # it's a lower case letter, so the bit is set.
                # Unless it's "l" (lower case L), which is special.
                if [ "$this_char" != "${this_char^}" ]  &&  [ "$this_char" != "l" ]
                then
                        let $((perms++))
                fi
                # If it's not "r", "w", "x", or "-", it indicates that
                # one of the high-order (S/s=4000, S/s/L/l=2000, or T/t=1000) bits
                # is set.
                case "$this_char" in
                  ([^rwx-])
                        let $((extra += 2 ** (3-i/3) ))
                esac
        done
        printf "%o%.3o\n" "$extra" "$perms"
done

उपर्युक्त में कुछ बाशिंदे शामिल हैं। निम्नलिखित संस्करण POSIX- संगत प्रतीत होता है:

#!/bin/sh
LC_COLLATE=C
while read ls_out
do
        extra=0
        perms=0
        for i in $(seq 1 9)
        do
                # Shift $perms to the left one bit, so we can always just add the LSB.
                : $((perms*=2))
                this_char=$(expr "$ls_out" : ".\{$i\}\(.\)")
                # Lower case letters other than "l" indicate that permission bits are set.
                # If it's not "r", "w", "x", or "-", it indicates that
                case "$this_char" in
                  (l)
                        ;;
                  ([a-z])
                        : $((perms+=1))
                esac
                # If it's not "r", "w", "x", or "-", it indicates that
                # one of the high-order (S/s=4000, S/s/L/l=2000, or T/t=1000) bits
                # is set.
                case "$this_char" in
                  ([!rwx-])
                        : $((extra += 1 << (3-i/3) ))
                esac
        done
        printf "%o%.3o\n" "$extra" "$perms"
done

टिप्पणियाँ:

  • LC_COLLATE=CASCII आदेश का उपयोग कर के रूप में इलाज पत्र अनुक्रम रेंज पैटर्न को खोल बताता है, तो [a-e]के बराबर है [abcde]। कुछ स्थानों में (उदाहरण के लिए, en_US), (यानी, ) या शायद के [a-e]बराबर है - देखें कि बैश केस स्टेटमेंट केस-सेंसिटिव क्यों नहीं है ...? )[aAbBcCdDeE][abcdeABCDE][abcdeABCD]
  • दूसरे संस्करण में (POSIX- शिकायत एक):

    • पहले caseबयान को फिर से लिखा जा सकता है:

              case "$this_char" in
                ([a-km-z])
                      : $((perms+=1))
              esac
      

      लेकिन मुझे लगता है कि जिस तरह से मेरे पास अब है वह यह देखना आसान बनाता है कि l वह पत्र जिसे अलग तरीके से संभाला जा रहा है। वैकल्पिक रूप से, इसे फिर से लिखा जा सकता है:

              case "$this_char" in
                ([rwxst])
                      : $((perms+=1))
              esac
      

      के बाद से r, w, x, s, और tकेवल अक्षर है कि कभी भी एक मोड स्ट्रिंग (के अलावा अन्य में दिखाई देनी चाहिए रहे हैं l)।

    • दूसरा caseकथन फिर से लिखा जा सकता है:

              case "$this_char" in
                ([rwx])
                      ;;
                ([A-Za-z])
                      : $((extra += 1 << (3-i/3) ))
               esac
      

      नियम को लागू करने के लिए कि मोड बिट्स को निर्दिष्ट करने के लिए केवल अक्षर मान्य हैं। (इसके विपरीत, पूर्ण स्क्रिप्ट में अधिक संक्षिप्त संस्करण आलसी है, और इसके -rw@rw#rw%बराबर के रूप में  स्वीकार करेगा rwSrwSrwT।) वैकल्पिक रूप से, इसे फिर से लिखा जा सकता है:

              case "$this_char" in
                ([SsTtLl])
                      : $((extra += 1 << (3-i/3) ))
              esac
      

      के बाद से S, s, T, t, L, और lकेवल अक्षर है कि कभी भी एक मोड स्ट्रिंग में दिखाई देनी चाहिए (अलावा अन्य कर रहे हैं r, wऔर x)।

उपयोग:

$ echo drwxr-xr-x | chmod-format
0755
$ echo -rwsr-sr-x | chmod-format
6755
$ echo -rwSr-Sr-- | chmod-format
6644
$ echo -rw-r-lr-- | chmod-format
2644
$ echo ---------- | chmod-format
0000

और, हां, मुझे पता है echoकि पाठ के साथ उपयोग न करना बेहतर है जो इसके साथ शुरू हो सकता है -; मैं सिर्फ प्रश्न से उपयोग उदाहरण की प्रतिलिपि बनाना चाहता था। ध्यान दें, जाहिर है, कि इस 0 चरित्र पर ध्यान नहीं देता (यानी, प्रमुख d/ b/ c/ -/ l/ p/ s/ D) और 10 वीं ( +/ ./ @)। यह मानता है कि देखरेख lsपरिभाषित करेगा कभी नहीं r/ Rया w/ Wतीसरे, छठे, या नौवें स्थिति में मान्य वर्ण के रूप में (और, अगर वे करते हैं, वे किया जाना चाहिए लाठियों से पीटा )।


इसके अलावा, मैं बस निम्नलिखित कोड पाया, कैस के तहत, कैसे / समूह के तहत सभी फ़ाइलों के डिफ़ॉल्ट समूह / उपयोगकर्ता स्वामित्व को पुनर्स्थापित करने के लिए :

        let perms=0

        [[ "${string}" = ?r???????? ]]  &&  perms=$(( perms +  400 ))
        [[ "${string}" = ??w??????? ]]  &&  perms=$(( perms +  200 ))
        [[ "${string}" = ???x?????? ]]  &&  perms=$(( perms +  100 ))
        [[ "${string}" = ???s?????? ]]  &&  perms=$(( perms + 4100 ))
        [[ "${string}" = ???S?????? ]]  &&  perms=$(( perms + 4000 ))
        [[ "${string}" = ????r????? ]]  &&  perms=$(( perms +   40 ))
        [[ "${string}" = ?????w???? ]]  &&  perms=$(( perms +   20 ))
        [[ "${string}" = ??????x??? ]]  &&  perms=$(( perms +   10 ))
        [[ "${string}" = ??????s??? ]]  &&  perms=$(( perms + 2010 ))
        [[ "${string}" = ??????S??? ]]  &&  perms=$(( perms + 2000 ))
        [[ "${string}" = ???????r?? ]]  &&  perms=$(( perms +    4 ))
        [[ "${string}" = ????????w? ]]  &&  perms=$(( perms +    2 ))
        [[ "${string}" = ?????????x ]]  &&  perms=$(( perms +    1 ))
        [[ "${string}" = ?????????t ]]  &&  perms=$(( perms + 1001 ))
        [[ "${string}" = ?????????T ]]  &&  perms=$(( perms + 1000 ))

मैंने इस कोड (लेकिन अच्छी तरह से नहीं) का परीक्षण किया है, और यह इस तथ्य को छोड़कर काम करने लगता है कि यह पहचान नहीं करता है lया Lछठे स्थान पर है। ध्यान दें, हालांकि, जबकि यह उत्तर सादगी और स्पष्टता के मामले में बेहतर है, मेरा वास्तव में कम है ( लूप के अंदर केवल कोड की गिनती ; वह कोड जो एक -rwxrwxrwxस्ट्रिंग को संभालता है , टिप्पणियों की गिनती नहीं), और इसे और भी छोटा बनाया जा सकता है। के साथ बदलकर ।if condition; then …condition && …


बेशक, आपको आउटपुट को पार्स नहीं करना चाहिएls


@ स्टीफनचेज़ेलैस: ठीक है, मैंने कहा #!/bin/shऔर फिर कुछ बशीज़ का इस्तेमाल किया। उफ़। लेकिन आपने एक जोड़े को याद किया: और ऐसा लगता है कि पोसिक्स या तो नहीं है (मानक बिल्कुल उल्लेख नहीं करता है , और गिलहरी पर और है )। इसके विपरीत, मैंने उपयोग नहीं किया ; यह केवल कैस के उत्तर में दिखाई देता है , जिसे मैंने यहां से उद्धृत किया है । इसके अलावा, मेरा जवाब 'l' और 'L' को हैंडल करता है, और मैंने पहले ही इस तथ्य पर ध्यान दिया है कि कैस का उत्तर नहीं है। $(( variable++ ))$(( number ** number ))**++-- [[…]]
स्कॉट

एल / एल [[के बारे में क्षमा करें, मैं बहुत जल्दी पढ़ता हूं। हाँ, - और ++ POSIX नहीं हैं। POSIX उन्हें लागू करने के लिए गोले की अनुमति देता है, इसका मतलब है कि आपको लिखना होगा $((- -a))यदि आप एक डबल नकार चाहते हैं, तो नहीं कि आप $((--a))एक क्षरण ऑपरेशन का उपयोग कर सकते हैं ।
स्टीफन क्लाजस

ध्यान दें कि seqPOSIX कमांड नहीं है। आप expr से बचने के लिए $ {var #?} ऑपरेटर का उपयोग करने में सक्षम हो सकते हैं। ऐसा नहीं है कि LC_COLLATE LC_ALL से आगे नहीं बढ़ेगा
स्टीफन चेज़लस

@ स्टीफनचेज़ेलस: ठीक है, आप कैस के उत्तर के बारे में फिर से बात कर रहे हैं, है ना? वह एक स्ट्रिंग का निर्माण करने के लिए दशमलव अंकगणित का उपयोग करने का "आलसी" दृष्टिकोण ले रहा है जो एक अष्टक संख्या की तरह दिखता है। ध्यान दें कि उसके सभी चरण मान (4000, 2000, 1000, 400, 200, 100, 40, 20, और 10) दशमलव संख्या हैं। लेकिन, चूंकि कोई 8's' या 9's' नहीं हैं, और 7किसी भी दशमलव स्थिति से अधिक पाने का कोई तरीका नहीं है , इसलिए वह वर्णसंकर खींच सकता है। ……………… (यह टिप्पणी एक स्टीफन चेज़लस टिप्पणी की प्रतिक्रिया है जो गायब हो गई।)
स्कॉट

हां, मुझे एहसास हुआ कि बाद में, यही वजह है कि मैंने टिप्पणी को हटा दिया।
स्टीफन चेज़लस

1

यदि आपका लक्ष्य एक फ़ाइल से अनुमति लेना है और उन्हें दूसरे को भी देना है, तो GNU के पास chmodपहले से ही इसके लिए एक "संदर्भ" विकल्प है


ओपी ने उल्लेख किया कि वह एप्पल ओएस / एक्स पर था, इसलिए वहां chmodजीएनयू नहीं chmodहोगा।
स्टीफन चेज़लस

आह, मैं दूसरे उत्तर पर टिप्पणी देख रहा हूँ जहाँ वे अपना मंच कहते हैं। मेरा केवल एक ही GNU का उल्लेख नहीं है और आप मैक ओएस एक्स पर जीएनयू यूटिलिटीज प्राप्त कर सकते हैं
ब्राचली

0

एक विकल्प, यदि आप अनुमतियों को दूर रखना चाहते हैं, तो उन्हें बाद में या किसी अन्य फ़ाइल पर पुनर्स्थापित करना है setfacl/getfacl, और यह एक बोनस के रूप में (POSIX- ड्राफ्ट) ACL को भी पुनर्स्थापित करेगा।

getfacl some-file > saved-perms
setfacl -M saved-perms some-other-file

(सोलारिस पर, -fइसके बजाय उपयोग करें -M)।

हालाँकि, कुछ बीएसडी पर उपलब्ध होने के बावजूद, वे Apple OS / X पर नहीं हैं जहाँ ACL के साथ chmodकेवल छेड़छाड़ की जाती है।


0

Mac OS X (10.6.8) पर आपको उपयोग करना होगा stat -f format(क्योंकि यह वास्तव में NetBSD / FreeBSD है stat)।

# using Bash

mods="$(stat -f "%p" ~)"    # octal notation
mods="${mods: -4}"
echo "$mods"

mods="$(stat -f "%Sp" ~)"  # symbolic notation
mods="${mods: -9}"
echo "$mods"

केवल ls -lअष्टक द्वारा निर्मित एक प्रतीकात्मक अनुमति स्ट्रिंग का अनुवाद करने के लिए (केवल शेल बिल्डिन का उपयोग करके) देखें: showperm.bash

# from: showperm.bash
# usage: showperm modestring
#
# example: showperm '-rwsr-x--x'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.