This is similar to using the Unix find
command to recursively set directory permissions. Often you want to do this to make sure that permissions on all directories under a given path are set to a specific value.
find /var/www/html -type d -exec chmod 750 {} \;
Today I decided I wanted to do it in Python. I created the following interactive script which takes two arguments: the path and the permission mode. For example it can be run like:
chmoddirs /var/www/html 750
If the user enters invalid data it will print a message and quit. If the data is valid then it asks for a confirmation before executing.
#!/usr/bin/python3 import sys, os, re # if 2 arguments not supplied print usage summary and exit if len(sys.argv) != 3: print("Usage: chmoddirs <path> <mode>") print("Where <mode> is similar to '755', '0755', etc.") exit() # Create regex for string representing valid permission modes, # octal values 0-7, optional 4th bit field validModes = re.compile("^[0-7][0-7][0-7][0-7]?$") pathErrorMsg = "" modeErrorMsg = "" # Check if argv[1] is a valid directory # ToDo: check to see if we actually have permission to chmod if not os.path.isdir(sys.argv[1]): pathErrorMsg = "Invalid argument: '" + sys.argv[1] + "' is not a directory" # Check if argv[2] is a valid mode if not validModes.match(sys.argv[2]): modeErrorMsg = "Invalid argument: Invalid mode: '" + sys.argv[2] + "'" # Display error messages # Both path and mode are invalid if pathErrorMsg != "" and modeErrorMsg != "": print(pathErrorMsg + "\n" + modeErrorMsg) exit() # Path is invalid elif pathErrorMsg != "": print(pathErrorMsg) exit() # Mode is invalid elif modeErrorMsg != "": print(modeErrorMsg) exit() # Prompt for confirmation print("Changing permissions for all directories under", sys.argv[1], "to", sys.argv[2]) userResponse = input('Proceed? (y/N)') while userResponse not in ['y', 'Y', 'n', 'N']: if userResponse == "": exit() print("Invalid choice") print("Changing permissions for all directories under", sys.argv[1], "to", sys.argv[2]) userResponse = input('Proceed? (y/N)') # User does not confirm if userResponse not in ['y', 'Y']: exit() # User confirms, perform operation else: # Cast argv[2] string to octal for os.chmod() mode = int(sys.argv[2], 8) for root, dirs, files in os.walk(sys.argv[1], topdown=True): for dir in dirs: os.chmod(os.path.join(root, dir), mode)
Leave a Reply
You must be logged in to post a comment.