Skip to content

Instantly share code, notes, and snippets.

@wwarriner
Forked from beugley/perm_to_text.py
Created June 5, 2024 19:20
Show Gist options
  • Save wwarriner/7eeed71816fe94f910ca2936bb7bbb9e to your computer and use it in GitHub Desktop.
Save wwarriner/7eeed71816fe94f910ca2936bb7bbb9e to your computer and use it in GitHub Desktop.
Python script to convert a Linux octal permission number to a text string
def perm_to_text(perm):
perms = {
"0": "---",
"1": "--x",
"2": "-w-",
"3": "-wx",
"4": "r--",
"5": "r-x",
"6": "rw-",
"7": "rwx"
}
if len(perm) == 4:
first = perm[0]
perm = perm[1:]
else:
first = ""
try:
outperms = ""
for p in perm:
outperms += perms[p]
except KeyError as e:
outperms = perm
if first != "":
if first == '0':
pass
elif first == '1':
pass
elif first == '2':
if outperms[5] == 'x':
outperms = outperms[:5]+'s'+outperms[6:]
else:
outperms = outperms[:5]+'S'+outperms[6:]
elif first == '4':
if outperms[2] == 'x':
outperms = outperms[:2]+'s'+outperms[3:]
else:
outperms = outperms[:2]+'S'+outperms[3:]
else:
outperms = perm
return "-"+outperms
@wwarriner
Copy link
Author

wwarriner commented Jun 5, 2024

From the original discussion c/o hack-tramp:

Warning : the above functions do NOT deal with four digit chmod octals.

When the octal is 4 digits long, the first digit is a setuid, setguid or sticky flag. See here for more info: https://linuxize.com/post/chmod-command-in-linux/ and here: https://en.wikipedia.org/wiki/File_system_permissions#Notation_of_traditional_Unix_permissions

Below is a version of the above function which correctly deals with four digit octals - be warned, it is not elegant!

def perm_to_text(octal):
   result =  ''
   first = 0
   octal = str(octal)
   #if there are more than 4 digits, just take the last 4
   if len(octal)>4:
      #separate initial digit
      octal = octal [-4:]
   #if there are 4 digits, deal with first (setuid, setgid, and sticky flags) separately
   if len(octal)==4:
      if octal[0]!='0': 
         first = int(octal [:1])
      octal = octal [-3:]
   value_letters = [(4, 'r'), (2, 'w'), (1, 'x')]
   # Iterate over each of the digits in octal
   for permission in [int(n) for n in octal]:
      # Check for each of the permissions values
      for value, letter in value_letters:
         if permission >= value:
            result += letter
            permission -= value
         else:
            result += '-'
   if first!=0:
      for value in [4,2,1]:
         if first >= value:
            if value==4:
               if result[2] == 'x':
                  result = result[:2]+'s'+result[3:]
               elif result[2] == '-':
                  result = result[:2]+'S'+result[3:]
            if value==2:
               if result[5] == 'x':
                  result = result[:5]+'s'+result[6:]
               elif result[5] == '-':
                  result = result[:5]+'S'+result[6:]            
            if value==1:
               if result[8] == 'x':
                  result = result[:8]+'t'+result[9:]
               elif result[8] == '-':
                  result = result[:8]+'T'+result[9:]             
            first -= value   
   
   return result

print(perm_to_text('3777'))
#rwxrwsrwt
print(perm_to_text('2775'))
#rwxrwsr-x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment