Test.sh script.



Here I’m test-driving a little script I wrote today. Its intent and purpose is to be as ‘universal’ as possible and become a template of sorts for later to be written scripts.

My intent: To write clear and concise scripts, to be repeated over and over again in an uniform fashion. All this without having ‘to bug’ the intended end-user (this would include me as well. 😆 )

The ‘openssl’ and ‘gpg’ functions as used in this script are for demonstration purposes only. I.e. I could simply have replaced the whole thing with:

echo "It works"

😆

The only thing I need to {edit,change} now, if I were to write a new {function,script}, is the text in between these two lines:

#************ THE ACTUAL SCRIPT STARTS HERE!!! *******************************#
code to be executed
exit 0
#*************** And IT BASICALLY ENDS HERE!!! *******************************#

Please read the comments to read what everything does. 😉
Smallish update!

The way I script, has considerably changed over time, here’s an example:

#!/bin/bash
##  I prefer bash, and the corresponding: “bash'isms” ; )
##  https://wiki.ubuntu.com/DashAsBinSh
##  http://wiki.bash-hackers.org/howto/getopts_tutorial
#
##  Modified: Today by E.L.F.
#
##  Licensed as:
##  http://www.opensource.org/licenses/mit-license.php
#
##  Script-name - cpdf.sh
##  http://www.ibm.com/developerworks/opensource/library/l-bash-parameters/index.html
#
##  Mandatory 'root' check ; )
##  Yes, you may disable this check, but ... I put it in here, for good reason.
##  You are hereby warned. ; )
if
  [[ "$UID" = "0" ]]
then
  ##  \u21 prints out an EXCLAMATION mark. ; )
  printf '%b\n' "\tError: There is no need to run this script as: \u201c "${USER^}"\u21 \u201d"
  exit 1
else
  Usage()
  {
  ##  Use "${FUNCNAME[N]}", for function-names.
  ##  The "${0##*/}" construct is the same,
  ##  as its "$(basename "$0")" construct. ; )
  printf '%b\n' "\tUsage: "${0##*/}" yourfile.pdf"
  exit 1
  }
  if
    [ -z "$1" ]
  then
    Usage
  else
    filetype="$(file --mime-type -b "$1"|awk -F'/' '{print $2}')"
    #  The following is based on:
    #  http://unix.stackexchange.com/questions/50475/how-to-make-ghostscript-not-wipe-pdf-metadata
    if [[ "$filetype" = "pdf" ]];then
      Arg="$1"
      Out="${1%.pdf}".opt.pdf
      TmpPdf=$(mktemp)
      MetaD=$(mktemp)
      ##  save metadata
      pdftk "$Arg" dump_data_utf8 > "$MetaD"
      ##  compress
      gs \
      -q \
      -sOutputFile="$TmpPdf" \
      -sDEVICE=pdfwrite \
      -dCompatibilityLevel=1.4 \
      -dPDFSETTINGS=/ebook \
      -dSAFER \
      -dNOPAUSE \
      -dQUIET \
      -dBATCH \
      "$Arg"
      ##  restore metadata
      pdftk "$TmpPdf" update_info_utf8 "$MetaD" output "$Out" # compress
      ##  clean up
      rm -f "$TmpPdf" "$MetaD"
      ##  Let's 'clobber' the old file, with the newer compressed one shall we. ; )
      ##  Since that's the one we're only interested in.
      mv "$Out" "$Arg" 2>&-
      unset Arg Out TmpPdf MetaD
    fi
  fi
fi
exit 0
#!/bin/bash
# Modified: Today by E.L.F.
#
## Licensed as:
## http://www.opensource.org/licenses/mit-license.php
#
## Script-name - test.sh
#
## Enables checking of all commands.
## If a command exits with an error and the caller does not check such error, the script aborts immediately.
## Enabling this will make your scripts more robust. <- Nope it won't!
#set -e
## Trace the program in bash before implementing.
#set -x
## 'Root' check, prevent user from 'burning' {him,her}self.
## ^ All this depends on the nature and purpose of the intended program.
## "It's better to be safe, than to be sorry."
## Or in Dutch: "Bezint eer gij begint."
case "$UID" in
"0")
## It's very unlikely to use 'Root' for daily simple {tasks,programs}.
## Unless you need specific access to system resources,
## your current account doesn't allow you to access.
## ^ If your system resides on a non {protected,encrypted} {partition,hard drive},
## then this 'limitation' can be easily overcome. *winks* <- Assuming ro access.
echo -e "\tError: \""$USER"\" isn't allowed to use this script!"
;;
"1000" | "1001" | "1002")
## This is in some need of tweaking!
## Separating admin users from less privileged users.
## Maybe 'a range' or 'array' of users will do?
  echo -e "\t${USER} may proceed.\n\tMay peace be with you.\n"
## Frome hereon end we run the commands we wish to run.
## But we're going to check first, if the desired commands to run exist.
## We use the program 'which' for this purpose.
## For more info:
# man which
  Which="/usr/bin/which"
  ## OK, it exists, but is its 'x' (execute) bit set?
  if [[ -x "$Which" ]];then
    ## I like to use colors to clarify my scripts.
    ## Therefore I'm checking to see if the user has the same setup as me.
    ## ^ Not mandatory though. *winks*
    Color_Test=$(grep -i '\\033\[' "$HOME"/.bashrc)
    if [ -n "$Color_Test" ];then echo -e ${Magenta}"\tOk, colors are defined.\n"${Nc}
    ## Because for the duration of this script I can still define them.
    else
    Black="\033[0;30m"
    Red="\033[0;31m"
    Green="\033[0;32m"
    Yellow="\033[1;33m"
    Blue="\033[1;34m"
    Magenta="\033[1;35m"
    Cyan="\033[1;36m"
    White="\033[1;37m"
    Nc="\033[0m" # No Color
    echo -e ${White}"\tThey weren't, but now they are."${Nc}
    fi
  clear
## So after 59 lines of tests, comments and defining things...
#************ THE ACTUAL SCRIPT STARTS HERE!!! *******************************#
## But it won't run as 'Root' (unless specifically required).
## And it will exit silently.
    ## Here we'll check to see if the intended program can run.
    ## If it doesn't, then this script will simply 'exit', without a hitch.
    if [[ -x "$(which openssl)" ]] && [[ -x "$(which gpg)" ]];then
      ## It's assumed here, that the first parameter aka '$1' is an 'option'.
      if [ -z "$2" ]; then
      echo -e ${Yellow}"\tError: Providing a filename is MANDATORY!"${Nc}
      echo -e ${Blue}"\tPlease choose a valid option!\n${Yellow}\tUsage:"${Nc}
      echo -e ${Cyan}"\tcrypto"${Nc}" {"${Cyan}"--encrypt"${Nc}","${Cyan}"-e"${Nc}"}\t${Blue} Your-file "${Nc}
      echo -e ${Cyan}"\tcrypto"${Nc}" {"${Cyan}"--decrypt"${Nc}","${Cyan}"-d"${Nc}"}\t${Blue} Your-file.aes "${Nc}
      echo -e ${Cyan}"\tcrypto"${Nc}" {"${Cyan}"--sign"${Nc}","${Cyan}"-s"${Nc}"}\t${Blue} Your-file "${Nc}
      echo -e ${Cyan}"\tcrypto"${Nc}" {"${Cyan}"--verify"${Nc}","${Cyan}"-v"${Nc}"}\t${Blue} Your-file.asc "${Nc}
      elif [ -d "$2" ]; then
      echo -e ${Yellow}"\tError: File is a directory!"${Nc}
      else
      ## Now about the option used.
      ## I'll work on a more flexible script later,
      ## One that uses the builtin 'shift' for example.
      case "$1" in
      "--encrypt" | "-e")
      ## to encrypt (-e):
      openssl aes-256-cbc -a -e -salt -in "$2" -out "$2".aes
      ;;
      "--decrypt" | "-d")
      ## to decrypt (-d):
      openssl aes-256-cbc -a -d -salt -in "$2" -out $(basename "$2" .aes)
      ;;
      "--sign" | "-s")
      ## to sign (-s):
      echo -e ${Cyan}"\tgpg -a --detach-sign \""$2"\""${Nc}
      gpg -a --detach-sign "$2"
      ;;
      "--verify" | "-v")
      ## to verify (-v):
      echo -e ${Cyan}"\tgpg --verify \""$2"\" \"$(basename "$2" .asc)\""${Nc}
      gpg --verify "$2" $(basename "$2" .asc)
      ;;
      *)
      echo -e ${Blue}"\tPlease choose a valid option!\n${Yellow}\tUsage:"${Nc}
      echo -e ${Cyan}"\tcrypto"${Nc}" {"${Cyan}"--encrypt"${Nc}","${Cyan}"-e"${Nc}"}\t${Blue} Your-file "${Nc}
      echo -e ${Cyan}"\tcrypto"${Nc}" {"${Cyan}"--decrypt"${Nc}","${Cyan}"-d"${Nc}"}\t${Blue} Your-file.aes "${Nc}
      echo -e ${Cyan}"\tcrypto"${Nc}" {"${Cyan}"--sign"${Nc}","${Cyan}"-s"${Nc}"}\t${Blue} Your-file "${Nc}
      echo -e ${Cyan}"\tcrypto"${Nc}" {"${Cyan}"--verify"${Nc}","${Cyan}"-v"${Nc}"}\t${Blue} Your-file.asc "${Nc}
      ;;
      esac
      fi
    fi
  fi
;;
*)
echo -e ${Cyan}"\tNOTHING DONE!"${Nc}
exit 0
;;
esac
exit 0
#*************** And IT BASICALLY ENDS HERE!!! *******************************#

And here is the result of running the above mentioned script on itself. 😆

./test.sh -e test.sh

With password: abcd

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

And here’s a screenshot of the script run without any arguments (i.e.: ./test.sh):

./test.sh

./test.sh

Tiny Matroska pinguins

Tiny Matroska pinguins (Photo credit: Act, don’t think)


That’s all folks! 😆

Kindest regards,

Alex

ღ Ƹ̵̡ Ӝ̵̨̄ Ʒ ☆ ˜ ” * ° • . ¸ł¸ . • ° * ” ☆ ★ ☆ ę ˜

♫ d(。◕‿◕。)b ♪♪

Use the contact-form below, for feedback purposes.







Back to top.