Advertisement
justin_hanekom

rsync-dir.sh

Mar 30th, 2019
257
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 7.21 KB | None | 0 0
  1. #!/bin/bash -
  2.  
  3. # File: rsync-dir.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='s:d:rvh'
  53. readonly LONGOPTS='srcdir:,destdir:,remove,verbose,help'
  54. readonly STARTED_AT=$(date '+%s')
  55.  
  56. # Global variable declarations
  57.  
  58. SRC_DIR=''
  59. DEST_DIR=''
  60. IS_REMOVE=''
  61. IS_VERBOSE=''
  62.  
  63. ################################################################################
  64. # Function:     chomp_slash
  65. # Description:  Removes any trailing slash ("/") from a string
  66. # Arguments:    $1 :- String from which to remove any trailing slashes
  67. # Ouputs:       Prints string with trailing slashes removed
  68. function chomp_slash {
  69.     local dir="$1"
  70.     while [ "${dir:(-1)}" = '/' ]; do
  71.         dir=${dir::-1}
  72.     done
  73.     echo "${dir}"
  74. }
  75.  
  76. ################################################################################
  77. # Function:     trim
  78. # Description:  Trims any/all whitespace from the beginning and end of a string
  79. # Arguments:    $1 :- The string from which to trim whitespace
  80. # Outputs:      Prints string with any leading/trailing whitespace removed
  81. function trim {
  82.     local str="$1"
  83.     str="${str#"${str%%[![:space:]]*}"}"
  84.    str="${str%"${str##*[![:space:]]}"}"
  85.     echo "$1"
  86. }
  87.  
  88. ################################################################################
  89. # Function:     usage_exit
  90. # Description:  Prints the usage message for this script and then exits
  91. # Arguments:    $1 :- Exit code; defaults to 1
  92. # Outputs:      Prints description of how to call this script
  93. function usage_exit {
  94.     local exit_code=1
  95.  
  96.     if [[ ${1-} =~ ^[0-9]+$ ]]; then
  97.         exit_code="$1"
  98.     fi
  99.  
  100.     cat << EOT
  101. Usage: $(basename "$0") [options]...
  102.     -s|--srcdir     <val>   (Required) The dir which is to be rsynced
  103.     -d|--destdir    <val>   (Required) The dir into which to rsync to <srcdir>
  104.     -r|--remove             Causes files that no longer exist in <srcdir>
  105.                             to be removed from <destdir>
  106.     -v|--verbose            Displays verbose output
  107.     -h|--help               Displays this message and aborts the script
  108.  
  109. NOTE: The <srcdir> and <destdir> arguments are mandatory and *must* be supplied
  110.  
  111. EOT
  112.     exit "${exit_code}"
  113. }
  114.  
  115. ################################################################################
  116. # Function:     parse_cmdline
  117. # Description:  Parses the command-line using the enhanced version of getopt
  118. # Arguments:    $@ :- Command-line arguments (required)
  119. # Requires:     Global variables $SRC_DIR, $DEST_DIR, $IS_REMOVE, and
  120. #               $IS_VERBOSE
  121. # Outputs:      Sets above-mentioned global variables based on given
  122. #               command-line arguments
  123. function parse_cmd_line {
  124.     # Ensure that the enhanced version of getopt is available
  125.  
  126.     ! getopt --test > /dev/null
  127.     if (( "${PIPESTATUS[0]}" != 4 )); then
  128.         echo "I'm sorry, the enhanced version of getopt is required. Exiting." >&2
  129.         exit 1
  130.     fi
  131.  
  132.     # Initialize the global variables
  133.  
  134.     SRC_DIR=''
  135.     DEST_DIR=''
  136.     IS_REMOVE=''
  137.     IS_VERBOSE=''
  138.  
  139.     # Parse the command-line options
  140.  
  141.     if ! readonly PARSED_OPTIONS=$(getopt --options=${OPTIONS} \
  142.                                     --longoptions=${LONGOPTS} \
  143.                                     --name "$(basename "$0")" -- "$@"); then
  144.         echo 'Unknown error parsing getopt options. Exiting.' >&2
  145.         exit 2
  146.     fi
  147.  
  148.     eval set -- "${PARSED_OPTIONS}"
  149.  
  150.     # Extract and validate command-line options and their arguments, if any
  151.  
  152.     while (( $# >= 1 )); do
  153.         case "$1" in
  154.             -s|--srcdir)
  155.                 SRC_DIR=$(chomp_slash "$(trim "$2")") ; shift 2
  156.                 ;;
  157.             -d|--destdir)
  158.                 DEST_DIR=$(chomp_slash "$(trim "$2")") ; shift 2
  159.                 ;;
  160.             -r|--remove)
  161.                 IS_REMOVE='true' ; shift
  162.                 ;;
  163.             -v|--verbose)
  164.                 IS_VERBOSE='true' ; shift
  165.                 ;;
  166.             -h|--help)
  167.                 usage_exit 0
  168.                 ;;
  169.             --)
  170.                 shift ; break
  171.                 ;;
  172.             *)
  173.                 usage_exit 3 >&2
  174.                 ;;
  175.         esac
  176.     done
  177.  
  178.     # Ensure that required options have been supplied
  179.  
  180.     if [[ -z "${SRC_DIR}" || -z "${DEST_DIR}" ]]; then
  181.         usage_exit 4 >&2
  182.     fi
  183. } # parse_cmd_line
  184.  
  185. ################################################################################
  186. # Start of program
  187.  
  188. parse_cmd_line "$@"
  189.  
  190. # Determine the rsync options
  191.  
  192. options='--archive --compress --partial'
  193. if [ -n "$IS_REMOVE" ]; then
  194.     options="${options} --delete"
  195. fi
  196.  
  197. if [ -n "$IS_VERBOSE" ]; then
  198.     options="${options} --progress --human-readable --stats"
  199. else
  200.     options="${options} --quiet"
  201. fi
  202.  
  203. # Rsync the source directory to the destination directory
  204.  
  205. if [ "${SRC_DIR:(-1)}" != '/' ]; then
  206.     SRC_DIR="${SRC_DIR}/"
  207. fi
  208.  
  209. # Note: the rsync options contains many options
  210. # and therefore eval is required
  211. eval "sudo rsync ${options} '${SRC_DIR}' '${DEST_DIR}'"
  212.  
  213. # Report that we are done, and how long the script took
  214.  
  215. if [ -n "$IS_VERBOSE" ]; then
  216.     readonly ENDED_AT=$(date '+%s')
  217.     readonly DIFF=$(( ENDED_AT - STARTED_AT ))
  218.     echo "Done, in ${DIFF} seconds"!
  219. fi
  220.  
  221. # 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