Anna Syme

Click name ↑ to return to homepage

Bash script - structure

#!/usr/bin/env bash

#Example of bash script structure

#............................................................................
# Defaults

set -e #exit if a command exits with non zero status
script=$(basename $0) #script name less file path
threads=16

#............................................................................
# Functions

function msg {
  echo -e "$*"
}
# $* is args passed in, -e means interpret backslashes

function msg_banner {
  printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
  msg "$*"
  printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
}
#prints a message inside dashed lines

function usage {
  msg "$script\n   This script does stuff."
  msg "Usage:\n   $script [options] R1.fq.gz"
  msg "Parameters:"
  msg "   R1 reads               R1.fq.gz"
  msg "Options:"
  msg "   -h                     Show this help"
  msg "   -t NUM                 Number of threads (default=16)"
  exit 1
  #exits script
}

#...........................................................................
# Parse the command line options

#loops through, sets variable or runs function
#have to add in a colon after the flag, if it's looking for an arg
#e.g. t: means flag t is set, then look for the arg (eg 32) to set $threads to
# : at the start disables default error handling for this bit
#instead it will label an odd flag as a ?
#the extra : at the end means it will label missing args as :

while getopts ':ht::' opt ; do
  case $opt in
    h)
      usage
      ;;
    t)
      threads=$OPTARG
      ;;
    \?)
      echo "Invalid option '=$OPTARG'"
      exit 1
      ;;
    :)
      echo "Option '-$OPTARG' requires an argument"
      exit 1
      ;;
  esac
done

shift $((OPTIND-1))
#remove all options that has been parsed by getopts
#so that $1 refers to next arg passed to script
#e.g. a positional arg

if [ $# -ne 1 ]; then
  msg "\n **Please provide one input parameter** \n"
  usage
fi
#if number of pos params is not 1, print usage msg

#...........................................................................
#start
msg "\n"
msg_banner "now running $script"

#...........................................................................
#check inputs

#give variable names to the input
raw_R1=$1

msg "This script will use:"
msg "   Illumina R1 reads:   $raw_R1" #positional arg
msg "   Threads:             $threads" #option setting or default

#...........................................................................
msg_banner "now activating conda env with tools needed"

source activate bio
#this activates the conda env called bio
#note - use source not conda

conda env export --name bio > conda_env_bio.yml
#saves this conda env

#...........................................................................
msg_banner "now getting seq stats"

seqkit stats $raw_R1 > R1.stats

msg "Script finished."