Advertisement
justin_hanekom

create-dpkg-list.sh

Mar 30th, 2019
257
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 8.33 KB | None | 0 0
  1. #!/bin/bash -
  2.  
  3. # File: create-dpkg-list.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:p:s:rvh'
  53. readonly LONGOPTS='user:,destdir:,prefix:,suffix:,remove,verbose,help'
  54. readonly DEF_PREFIX='dpkg_'
  55. readonly DEF_SUFFIX='.txt'
  56. readonly TIMESTAMP=$(date '+%Y%m%d%H%M%S')
  57. readonly STARTED_AT=$(date '+%s')
  58.  
  59. # Global variable declarations
  60.  
  61. USER_NAME=''
  62. DESTDIR=''
  63. PREFIX="${DEF_PREFIX}"
  64. SUFFIX="${DEF_SUFFIX}"
  65. IS_REMOVE=''
  66. IS_VERBOSE=''
  67.  
  68. ################################################################################
  69. # Function:     chomp_slash
  70. # Description:  Removes any trailing slash ("/") from a string
  71. # Arguments:    $1 :- String from which to remove any trailing slashes
  72. # Ouputs:       Prints string with trailing slashes removed
  73. function chomp_slash {
  74.     local dir="$1"
  75.     while [ "${dir:(-1)}" = '/' ]; do
  76.         dir=${dir::-1}
  77.     done
  78.     echo "${dir}"
  79. }
  80.  
  81. ################################################################################
  82. # Function:     echo_if_verbose
  83. # Description:  Prints $@ if IS_VERBOSE is not empty
  84. # Arguments:    $@ :- Content to echo if ${IS_VERBOSE} is not empty
  85. # Requires:     ${IS_VERBOSE} set to a non-empty string if verbose is on
  86. # Outputs:      Prints $@ if ${IS_VERBOSE} is not empty
  87. function echo_if_verbose {
  88.     if [ -n "${IS_VERBOSE}" ]; then
  89.         echo "$@"
  90.     fi
  91. }
  92.  
  93. ################################################################################
  94. # Function:     trim
  95. # Description:  Trims any/all whitespace from the beginning and end of a string
  96. # Arguments:    $1 :- The string from which to trim whitespace
  97. # Outputs:      Prints string with any leading/trailing whitespace removed
  98. function trim {
  99.     local str="$1"
  100.     str="${str#"${str%%[![:space:]]*}"}"
  101.    str="${str%"${str##*[![:space:]]}"}"
  102.     echo "$1"
  103. }
  104.  
  105. ################################################################################
  106. # Function:     usage_exit
  107. # Description:  Prints the usage message for this script and then exits
  108. # Arguments:    $1 :- Exit code; defaults to 1
  109. # Outputs:      Prints description of how to call this script
  110. function usage_exit {
  111.     local exit_code=1
  112.  
  113.     if [[ ${1-} =~ ^[0-9]+$ ]]; then
  114.         exit_code="$1"
  115.     fi
  116.  
  117.     cat << EOT
  118. Usage: $(basename "$0") [options]...
  119.     -u|--user       <val>   (Required) The owner of the directory and content
  120.     -d|--destdir    <val>   (Required) The directory whose owner has to be set
  121.     -p|--prefix             The prefix to give the dpkg list; default 'dpkg_'
  122.     -s|--suffix             The suffix to give the dpkg list; defaults to '.txt'
  123.     -r|--remove             Causes previous dpkg list files to be removed
  124.     -v|--verbose            Displays verbose output
  125.     -h|--help               Displays this message and exits the script
  126.  
  127. NOTE: The <user> and <destdir> arguments are mandatory and *must* be supplied
  128.  
  129. EOT
  130.     exit "${exit_code}"
  131. }
  132.  
  133. ################################################################################
  134. # Function:     parse_cmd_line
  135. # Description:  Parses the command-line using the enhanced version of getopt
  136. # Arguments:    $@ :- Command-line arguments (required)
  137. # Requires:     Global variables $USER_NAME, $DESTDIR, $PREFIX, $SUFFIX,
  138. #               $IS_REMOVE, and $S_VERBOSE
  139. # Outputs:      Sets above-mentioned global variables based on given
  140. #               command-line arguments
  141. function parse_cmd_line {
  142.     # Ensure that the enhanced version of getopt is available
  143.  
  144.     ! getopt --test > /dev/null
  145.     if (( "${PIPESTATUS[0]}" != 4 )); then
  146.         echo "I'm sorry, the enhanced version of getopt is required. Exiting." >&2
  147.         exit 1
  148.     fi
  149.  
  150.     # Initialize the global variables
  151.  
  152.     USER_NAME=''
  153.     DESTDIR=''
  154.     PREFIX="${DEF_PREFIX}"
  155.     SUFFIX="${DEF_SUFFIX}"
  156.     IS_REMOVE=''
  157.     IS_VERBOSE=''
  158.  
  159.     # Parse the command-line options
  160.  
  161.     if ! readonly PARSED_OPTIONS=$(getopt --options=${OPTIONS} \
  162.                                     --longoptions=${LONGOPTS} \
  163.                                     --name "$(basename "$0")" -- "$@"); then
  164.         echo 'Unknown error parsing getopt options. Exiting.' >&2
  165.         exit 2
  166.     fi
  167.  
  168.     eval set -- "${PARSED_OPTIONS}"
  169.  
  170.     # Extract command-line options and their arguments, if any
  171.  
  172.     while (( $# >= 1 )); do
  173.         case "$1" in
  174.             -u|--user)
  175.                 USER_NAME=$(trim "$2") ; shift 2
  176.                 ;;
  177.             -d|--destdir)
  178.                 DESTDIR=$(chomp_slash "$2") ; shift 2
  179.                 ;;
  180.             -p|--prefix)
  181.                 PREFIX=$(trim "$2"); shift 2
  182.                 ;;
  183.             -s|--suffix)
  184.                 SUFFIX=$(trim "$2"); shift 2
  185.                 ;;
  186.             -r|--remove)
  187.                 IS_REMOVE='true' ; shift
  188.                 ;;
  189.             -v|--verbose)
  190.                 IS_VERBOSE='true' ; shift
  191.                 ;;
  192.             -h|--help)
  193.                 usage_exit 0
  194.                 ;;
  195.             --)
  196.                 shift ; break
  197.                 ;;
  198.             *)
  199.                 usage_exit 3 >&2
  200.                 ;;
  201.         esac
  202.     done
  203.  
  204.     # Ensure that required options have been supplied
  205.  
  206.     if [[ -z "${USER_NAME}" || -z "${DESTDIR}" ]]; then
  207.         usage_exit 4 >&2
  208.     fi
  209. } # parse_cmd_line
  210.  
  211. ################################################################################
  212. # Start of program
  213.  
  214. parse_cmd_line "$@"
  215. readonly DEST_FILENAME="${DESTDIR}/${PREFIX}${TIMESTAMP}${SUFFIX}"
  216.  
  217. # Optionally remove any previous dpkg list file
  218.  
  219. if [ -n "$IS_REMOVE" ]; then
  220.     sudo rm --force "${DESTDIR}"/"${PREFIX}"*"${SUFFIX}" &>/dev/null
  221.     echo_if_verbose "Removed: ${DESTDIR}/${PREFIX}*${SUFFIX}"
  222. fi
  223.  
  224. # Create the dpkg list file
  225.  
  226. dpkg -l | grep --extended-regexp '^ii' | \
  227.     perl -F'\s\s+' -alne 'printf("%s [%s] %s\n",$F[1],$F[2],splice(@F,4))' | \
  228.     sudo tee "${DEST_FILENAME}" 1>/dev/null
  229. echo_if_verbose "Stored 'dpkg -l' to: ${DEST_FILENAME}"
  230.  
  231. # Change the owner of the generated dpkg list file
  232.  
  233. sudo chown "${USER_NAME}":"${USER_NAME}" "${DEST_FILENAME}"
  234. echo_if_verbose "Changed owner of: ${DEST_FILENAME} to: ${USER_NAME}"
  235.  
  236. # Report that we are done, and how long the script took
  237.  
  238. if [ -n "$IS_VERBOSE" ]; then
  239.     readonly ENDED_AT=$(date '+%s')
  240.     readonly DIFF=$(( ENDED_AT - STARTED_AT ))
  241.     echo "Done, in ${DIFF} seconds"!
  242. fi
  243.  
  244. # 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