-
-
Save beugley/47b4812df0837fc90e783347faee2432 to your computer and use it in GitHub Desktop.
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 |
Thanks! @mpdrsn
Thanks @mpdrsn so much.
Thank u
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
Thanks for writing and posting this! This was very helpful in writing my own parser. If you need to convert from symbolic to numeric you can use this function.
def perm_to_num(symbolic):
'''
Convert symbolic permission notation to numeric notation.
'''
perms = {
'---': '0',
'--x': '1',
'-w-': '2',
'-wx': '3',
'r--': '4',
'r-x': '5',
'rw-': '6',
'rwx': '7'
}
# Trim Lead If It Exists
if len(symbolic) == 10:
symbolic = symbolic[1:]
# Parse Symbolic to Numeric
x = (symbolic[:-6], symbolic[3:-3], symbolic[6:])
numeric = perms[x[0]] + perms[x[1]] + perms[x[2]]
return numeric
This will convert input like '-rw-r--r--' to '644'
Sorry, my function does exactly the reverse of the initial question... It's like the post from Justin Timperio
I have a version which handles the additional permissions like Sticky bit, Set User/Group bits. For instance, it converts 'rwsr-Sr-T'. Note that my code is extracted from my tools and allows to pass an octal value (usually a mistake). Here is the code 👍
def set_fmode(value) :
"""
Convert a 'rwsr-xr-T' format to a decimal value
"""
lvalue = len(value)
# Check if 'value' has the right format
if (isinstance(value,
str)
and not [x for x in value if x not in '-rwxXsStT']
and lvalue == 9) :
pos = lvalue - 1
res = 0
for c in value :
if c in 'sStT' :
# Special modes
res += (1 << pos // 3) << 9
res += 1 << pos if c in 'rwxst' else 0
pos -= 1
elif isinstance(value,
int) :
res = value
else :
raise ValueError
return res
import stat
stat.filemode(0o107664) # '-rwSrwSr-T'
How about something simpler (sorry for the formatting):
def perm_to_text(octal):
result = ""
value_letters = [(4, "r"), (2, "w"), (1, "x")]
# Iterate over each of the digits in octal
for permission in [int(n) for n in str(octal)]:
# Check for each of the permissions values
for value, letter in value_letters:
if permission >= value:
result += letter
permission -= value
else:
result += "-"
return result