Advertisement
justin_hanekom

chown-dir-user.sh

Mar 30th, 2019
328
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 6.82 KB | None | 0 0
  1. #!/bin/bash -
  2.  
  3. # File: chown-dir-user.sh
  4. # Copyright (c) 2018-2019 Justin Hanekom <justin_hanekom@yahoo.com>
  5. # Licensed under the MIT License
  6.  
  7. # Permission is hereby granted, free of charge, to any person obtaining
  8. # a copy of this software and associated documentation files
  9. # (the "Software"), to deal in the Software without restriction,
  10. # including without limitation the rights to use, copy, modify, merge,
  11. # publish, distribute, sublicense, and/or sell copies of the Software,
  12. # and to permit persons to whom the Software is furnished to do so,
  13. # subject to the following conditions:
  14. #
  15. # The above copyright notice and this permission notice shall be
  16. # included in all copies or substantial portions of the Software.
  17. #
  18. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19. # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  21. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  22. # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23. # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24. # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  
  26. # Setup a safe Bash scripting environment
  27.  
  28. set -o errexit      # Exit immediately if an error occurs
  29. set -o noclobber    # Do not allow files to be overwritten via redirect
  30. set -o nounset      # Do not allow unset variables
  31.  
  32. # Set the exit code of a pipeline to the rightmost non-zero on error
  33. set -o pipefail
  34. #set -o xtrace       # Trace script execution (i.e., debug mode)
  35. # Set the internal field separator to newline or tab, but not space
  36. IFS=$'\n\t'
  37.  
  38. # Setup a secure Bash scripting environment by: setting a secure path;
  39. # clearing all aliases; clearing the command path hash; setting the hard limit
  40. # to 0 to turn off core dumps; and setting a secure umask
  41.  
  42. PATH=$(PATH='/bin:/usr/bin' getconf PATH); export PATH
  43. builtin unalias -a
  44. hash -r
  45. ulimit -H -c 0 --
  46.  
  47. UMASK=002
  48. umask ${UMASK}
  49.  
  50. # Global constant definitions
  51.  
  52. readonly OPTIONS='u:d:vh'
  53. readonly LONGOPTS='user:,directory:,verbose,help'
  54. readonly STARTED_AT=$(date '+%s')
  55.  
  56. # Global variable declarations
  57.  
  58. USER_NAME=''
  59. DIR=''
  60. IS_VERBOSE=''
  61.  
  62. ################################################################################
  63. # Function:     chomp_slash
  64. # Description:  Removes any trailing slash ("/") from a string
  65. # Arguments:    $1 :- String from which to remove any trailing slashes
  66. # Ouputs:       Prints string with trailing slashes removed
  67. function chomp_slash {
  68.     local dir="$1"
  69.     while [ "${dir:(-1)}" = '/' ]; do
  70.         dir=${dir::-1}
  71.     done
  72.     echo "${dir}"
  73. }
  74.  
  75. ################################################################################
  76. # Function:     trim
  77. # Description:  Trims any/all whitespace from the beginning and end of a string
  78. # Arguments:    $1 :- The string from which to trim whitespace
  79. # Outputs:      Prints string with any leading/trailing whitespace removed
  80. function trim {
  81.     local str="$1"
  82.     str="${str#"${str%%[![:space:]]*}"}"
  83.    str="${str%"${str##*[![:space:]]}"}"
  84.     echo "$1"
  85. }
  86.  
  87. ################################################################################
  88. # Function:     usage_exit
  89. # Description:  Prints the usage message for this script and then exits
  90. # Arguments:    $1 :- Exit code; defaults to 1
  91. # Outputs:      Prints description of how to call this script
  92. function usage_exit {
  93.     local exit_code=1
  94.  
  95.     if [[ ${1-} =~ ^[0-9]+$ ]]; then
  96.         exit_code="$1"
  97.     fi
  98.  
  99.     cat << EOT
  100. Usage: $(basename "$0") [options]...
  101.     -u|--user      <val>   (Required) The owner of the directories content
  102.     -d|--directory <val>   (Required) The root directory
  103.     -v|--verbose            Displays verbose output
  104.     -h|--help               Displays this message and aborts the script
  105.  
  106. NOTE: The <user> and <dir> arguments are mandatory and *must* be supplied
  107.  
  108. EOT
  109.     exit "${exit_code}"
  110. }
  111.  
  112. ################################################################################
  113. # Function:     parse_cmd_line
  114. # Description:  Parses the command-line using the enhanced version of getopt
  115. # Arguments:    $@ :- Command-line arguments (required)
  116. # Requires:     Global variables $USER_NAME, $DIR, and $IS_REMOVE
  117. # Outputs:      Sets above-mentioned global variables based on given
  118. #               command-line arguments
  119. function parse_cmd_line {
  120.     # Ensure that the enhanced version of getopt is available
  121.  
  122.     ! getopt --test > /dev/null
  123.     if (( "${PIPESTATUS[0]}" != 4 )); then
  124.         echo "I'm sorry, the enhanced version of getopt is required. Exiting." >&2
  125.         exit 1
  126.     fi
  127.  
  128.     # Initialize the global variables
  129.  
  130.     USER_NAME=''
  131.     DIR=''
  132.     IS_VERBOSE=''
  133.  
  134.     # Parse the command-line options
  135.  
  136.     if ! readonly PARSED_OPTIONS=$(getopt --options=${OPTIONS} \
  137.                                     --longoptions=${LONGOPTS} \
  138.                                     --name "$(basename "$0")" -- "$@"); then
  139.         echo 'Unknown error parsing getopt options. Exiting.' >&2
  140.         exit 2
  141.     fi
  142.  
  143.     eval set -- "${PARSED_OPTIONS}"
  144.  
  145.     # Extract command-line options and their arguments, if any
  146.  
  147.  
  148.     while (( $# >= 1 )); do
  149.         case "$1" in
  150.             -u|--user)
  151.                 USER_NAME=$(trim "$2") ; shift 2
  152.                 ;;
  153.             -d|--directory)
  154.                 DIR=$(chomp_slash "$(trim "$2")") ; shift 2
  155.                 ;;
  156.             -v|--verbose)
  157.                 IS_VERBOSE='true' ; shift
  158.                 ;;
  159.             -h|--help)
  160.                 usage_exit 0
  161.                 ;;
  162.             --)
  163.                 shift ; break
  164.                 ;;
  165.             *)
  166.                 usage_exit 3 >&2
  167.                 ;;
  168.         esac
  169.     done
  170.  
  171.     # Ensure that required options have been supplied
  172.  
  173.     if [[ -z "${USER_NAME}" || -z "${DIR}" ]]; then
  174.         usage_exit 4 >&2
  175.     fi
  176. } # parse_cmd_line
  177.  
  178. ################################################################################
  179. # Start of program
  180.  
  181. parse_cmd_line "$@"
  182.  
  183. # Ensure that all directories and files under ${DIR} belong to ${USER_NAME}
  184.  
  185. if [ -n "${IS_VERBOSE}" ]; then
  186.     verbose_flag='--verbose'
  187. else
  188.     verbose_flag=''
  189. fi
  190.  
  191. # Note: grep is used to ignore any sbin directories
  192. # as they could have files that must be owned by root
  193. sudo find "${DIR}" -mount -not -user "${USER_NAME}" -or -not -group "${USER_NAME}" | \
  194.     grep --extended-regexp --invert-match '\bsbin\b' | \
  195.     sudo xargs chown "${verbose_flag}" "${USER_NAME}":"${USER_NAME}" 2>/dev/null
  196.  
  197. # Report that we are done, and how long the script took
  198.  
  199. if [ -n "$IS_VERBOSE" ]; then
  200.     readonly ENDED_AT=$(date '+%s')
  201.     readonly DIFF=$(( ENDED_AT - STARTED_AT ))
  202.     echo "Done, in ${DIFF} seconds"!
  203. fi
  204.  
  205. # vim: set filetype=sh smartindent autoindent smarttab expandtab tabstop=4 softtabstop=4 shiftwidth=4 autoread
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement