fant0men

arch_pack.sh

Jul 29th, 2019 (edited)
200
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/bash
  2. # This script compresses files / directories to archives (in chosen
  3. # format) and then lets you know if there were errors or not. In all
  4. # cases, the script uses maximum compression level.
  5.  
  6. set -o pipefail
  7.  
  8. # Creates a variable ($f) with the archive name, which is supposed to be
  9. # the first argument to the script.
  10. f=$(readlink -f "$1")
  11. f_bn=$(basename "$f")
  12. of=$(sed -E 's/(\.[0-z]{2,3}){1,2}$//' <<<"$1")
  13. stderr_f="/dev/shm/arch_pack_stderr-${RANDOM}.txt"
  14. c_tty=$(tty)
  15.  
  16. # trap ctrl-c and call ctrl_c()
  17. trap ctrl_c INT
  18.  
  19. ctrl_c () {
  20.     restore
  21.     echo '** Trapped CTRL-C'
  22.     exit
  23. }
  24.  
  25. restore () {
  26.     exec 2>"$c_tty"
  27.     cat_stderr
  28.     rm -f "$stderr_f"
  29. }
  30.  
  31. cat_stderr () {
  32.     stderr_out=$(cat "$stderr_f")
  33.  
  34.     truncate -s 0 "$stderr_f"
  35.  
  36.     if [[ $stderr_out ]]; then
  37.         echo "$stderr_out"
  38.     fi
  39. }
  40.  
  41. touch "$stderr_f"
  42. exec 2>>"$stderr_f"
  43.  
  44. # Creates an array ($files) with all the files and directories to be
  45. # compressed.
  46. files=("$@")
  47.  
  48. # Deletes the first element of the files array, because that's the
  49. # intended name of the archive, and not a file to be compressed.
  50. unset -v files[0]
  51.  
  52. # This function echoes usage instructions and then exits.
  53. usage () {
  54.     cat <<USAGE
  55. Usage: $(basename "$0") [archive] [files...]
  56.  
  57. Supported archive formats are:
  58.  
  59. tar, tar.bz2|tbz|tbz2, tar.xz|txz, tar.gz|tgz, zip, 7z, rar
  60.  
  61. USAGE
  62.  
  63.     exit
  64. }
  65.  
  66. # Creates a function, called 'check_cmd', which will be used to
  67. # check if the needed commands are installed.
  68. check_cmd () {
  69.     check() {
  70.         command -v "$1"
  71.     }
  72.  
  73.     declare -A cmd name
  74.  
  75.     cmd[dar]=$(check 'dar')
  76.     cmd[7z]=$(check '7za')
  77.     cmd[rar]=$(check 'rar')
  78.     cmd[cab]=$(check 'cabextract')
  79.     cmd[arj]=$(check '7z')
  80.  
  81.     name[dar]='dar'
  82.     name[7z]='7zip'
  83.     name[rar]='rar'
  84.     name[cab]='cabextract'
  85.     name[arj]='7zip'
  86.  
  87.     for cmd_type in ${!cmd[@]}; do
  88.         if [[ $1 == $cmd_type ]]; then
  89.             if [[ -z ${cmd[${cmd_type}]} ]]; then
  90.                 cat <<CMD
  91.  
  92. '${name[${cmd_type}]}' is not installed!
  93. Install it through your package manager.
  94.  
  95. In the case of 'rar', you can get the Linux version for free @ https://www.rarlab.com/download.htm
  96. Put the 'rar' executable in ${HOME}/bin, and make sure that this directory is in your PATH variable.
  97. You can modify your PATH variable by editing ${HOME}/.bashrc, and adding this line:
  98.  
  99. PATH="\${HOME}/bin:\${PATH}"
  100.  
  101. CMD
  102.                 exit
  103.             fi
  104.         fi
  105.     done
  106. }
  107.  
  108. # Creates a function, called 'output', which will let the user know if
  109. # the extraction went okay or not. If not, print the entire output from
  110. # the compression program.
  111. output () {
  112.     print_stdout () {
  113.         for (( n = 0; n < ${last}; n++ )); do
  114.             echo "${stdout_v[${n}]}"
  115.         done
  116.         unset -v stdout_v
  117.         cat_stderr
  118.     }
  119.  
  120.     if [[ ${#stdout_v[@]} -gt 0 ]]; then
  121.         last=$(( ${#stdout_v[@]} - 1 ))
  122.     fi
  123.  
  124.     if [[ ${stdout_v[${last}]} -ne 0 ]]; then
  125.         echo -e "${f}: Something went wrong\n"
  126.         print_stdout
  127.     else
  128.         echo -e "${f}: Everything is Ok\n"
  129. #       print_stdout
  130.     fi
  131. }
  132.  
  133. # Creates a function, called 'tar_f', which will output an intermediate TAR
  134. # archive to STDOUT, to be piped into a compression program.
  135. tar_f () {
  136.     tar -c "${files[@]}"
  137. }
  138.  
  139. # Creates a function, called 'exists', which will check if a file
  140. # already exists, and if so it quits running the script.
  141. exists () {
  142.     if [[ -f $f ]]; then
  143.         echo -e "${f}: File already exists\n"
  144.         exit
  145.     fi
  146. }
  147.    
  148. # If there are no arguments to the script, print usage and then exit.
  149. if [[ -z $1 || -z $2 ]]; then
  150.     usage
  151. fi
  152.  
  153. # If an archive with the same name already exists, quit.
  154. exists
  155.  
  156. # Depending on the filename extension, create an archive accordingly.
  157. case "$f" in
  158.     *.tar)
  159.         mapfile -t stdout_v < <(tar -cf "${of}.tar" "${files[@]}"; echo "$?")
  160.         output
  161.     ;;
  162.     *.tar.bz2|*.tbz|*.tbz2)
  163.         mapfile -t stdout_v < <(tar_f "$f" | bzip2 --compress -9 > "${of}.tar.bz2"; echo "$?")
  164.         output
  165.     ;;
  166.     *.tar.xz|*.txz)
  167.         mapfile -t stdout_v < <(tar_f "$f" | xz --compress -9 > "${of}.tar.xz"; echo "$?")
  168.         output
  169.     ;;
  170.     *.tar.gz|*.tgz)
  171.         mapfile -t stdout_v < <(tar_f "$f" | gzip -9 > "${of}.tar.gz"; echo "$?")
  172.         output
  173.     ;;
  174.     *.zip)
  175.         mapfile -t stdout_v < <(zip -r -9 "$f" "${files[@]}"; echo "$?")
  176.         output
  177.     ;;
  178.     *.7z)
  179.         check_cmd 7z
  180.  
  181.         mapfile -t stdout_v < <(7za a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on "$f" "${files[@]}"; echo "$?")
  182.         output
  183.     ;;
  184.     *.rar)
  185.         check_cmd rar
  186.  
  187.         mapfile -t stdout_v < <(rar a -m5 "$f" "${files[@]}"; echo "$?")
  188.         output
  189.     ;;
  190.     *)
  191.         usage
  192.     ;;
  193. esac
  194.  
  195. restore
  196.  
RAW Paste Data