-if [[ -d "$DIROUT1" ]] && command -v "gpspipe" 1>/dev/null 2>/dev/null ; then
-    while true; do
-       #echoerr "DEBUG:Starting while loop."
-       # Update time constants
-       TIME_CURRENT="$(date --iso-8601=seconds)" ;
-       #echoerr "DEBUG:TIME_CURRENT is:""$TIME_CURRENT" ;
-       TIME_CURRENT_SHORT="$(date -d "$TIME_CURRENT" +%Y%m%dT%H%M%S%z)"
-       #echoerr "DEBUG:TIME_CURRENT_SHORT is""$TIME_CURRENT_SHORT"
-       DATE_CURRENT="$(date -d "$TIME_CURRENT" --iso-8601=date)" ;
-       #echoerr "DEBUG:DATE_CURRENT is:""$DATE_CURRENT" ;
-       DATE_CURRENT_SHORT="$(date -d "$TIME_CURRENT" +%Y%m%d)" ;
-       #echoerr "DEBUG:DATE_CURRENT is:""$DATE_CURRENT_SHORT" ;
-       DATE_TOMORROW="$(date -d "$TIME_CURRENT next day" --iso-8601=date)" ;
-       #echoerr "DEBUG:DATE_TOMORROW is:""$DATE_TOMORROW" ;
-       TIME_NEXT_MIDNIGHT="$(date -d "$DATE_TOMORROW" --iso-8601=seconds)" ;
-       #echoerr "DEBUG:TIME_NEXT_MIDNIGHT is:""$TIME_NEXT_MIDNIGHT" ;
-       SECONDS_UNTIL_NEXT_MIDNIGHT="$((  $(date +%s -d "$TIME_NEXT_MIDNIGHT") - $(date +%s -d "$TIME_CURRENT")  ))" ;
-       #echoerr "DEBUG:SECONDS_UNTIL_NEXT_MIDNIGHT is:""$SECONDS_UNTIL_NEXT_MIDNIGHT" ;
-       if [ "$SECONDS_UNTIL_NEXT_MIDNIGHT" -eq 0 ]; then echoerr "WARNING:Is it exactly midnight?" ; continue; fi ; # Exit loop early if equal to 0 because "timeout 0s" never ends.
-       if [ "$SECONDS_UNTIL_NEXT_MIDNIGHT" -lt 0 ]; then echoerr "ERROR:Time until midnight error." ; exit 1; fi ; # Exit script if equal to 0 because "timeout 0s" never ends.
+    ## Output duration string to stdout
+    echo "$OUTPUT" && returnState="true";
+
+    #===Determine function return code===
+    if [ "$returnState" = "true" ]; then
+       return 0;
+    elif [ "$returnState" = "error_input" ]; then
+       yell "ERROR:input";
+       return 1;
+    else
+       yell "ERROR:Unknown";
+       return 2;
+    fi
+
+} # Get duration (ex: PT10M4S )
+displayMissing() {
+    # Desc: Displays missing apps, files, and dirs
+    # Usage: displayMissing
+    # Input: associative arrays: appRollCall, fileRollCall, dirRollCall
+    # Output: stderr messages
+    #==BEGIN Display errors==
+    #===BEGIN Display Missing Apps===
+    missingApps="Missing apps  :"
+    #for key in "${!appRollCall[@]}"; do echo "DEBUG:$key => ${appRollCall[$key]}"; done
+    for key in "${!appRollCall[@]}"; do
+       value="${appRollCall[$key]}"
+       if [ "$value" = "false" ]; then
+           #echo "DEBUG:Missing apps: $key => $value";
+           missingApps="$missingApps""$key "
+           appMissing="true"
+       fi
+    done
+    if [ "$appMissing" = "true" ]; then  # Only indicate if an app is missing.
+       echo "$missingApps" 1>&2;
+    fi
+    #===END Display Missing Apps===
+
+    #===BEGIN Display Missing Files===
+    missingFiles="Missing files:"
+    #for key in "${!fileRollCall[@]}"; do echo "DEBUG:$key => ${fileRollCall[$key]}"; done
+    for key in "${!fileRollCall[@]}"; do
+       value="${fileRollCall[$key]}"
+       if [ "$value" = "false" ]; then
+           #echo "DEBUG:Missing files: $key => $value";
+           missingFiles="$missingFiles""$key "
+           fileMissing="true"
+       fi
+    done
+    if [ "$fileMissing" = "true" ]; then  # Only indicate if an app is missing.
+       echo "$missingFiles" 1>&2;
+    fi
+    #===END Display Missing Files===
+
+    #===BEGIN Display Missing Directories===
+    missingDirs="Missing dirs:"
+    #for key in "${!dirRollCall[@]}"; do echo "DEBUG:$key => ${dirRollCall[$key]}"; done
+    for key in "${!dirRollCall[@]}"; do
+       value="${dirRollCall[$key]}"
+       if [ "$value" = "false" ]; then
+           #echo "DEBUG:Missing dirs: $key => $value";
+           missingDirs="$missingDirs""$key "
+           dirMissing="true"
+       fi
+    done
+    if [ "$dirMissing" = "true" ]; then  # Only indicate if an dir is missing.
+       echo "$missingDirs" 1>&2;
+    fi
+    #===END Display Missing Directories===
+
+    #==END Display errors==
+} # Display missing apps, files, dirs
+setScriptTTL() {
+    #Desc: Sets script TTL
+    #Usage: setScriptTTL arg1
+    #Input: arg1: "day" or "hour"
+    #Output: scriptTTL
+    #Depends: timeUntilNextHour or timeUntilNextDay
+    local ARG1
+    ARG1="$1"
+    if [[ "$ARG1" = "day" ]]; then
+           # Set script lifespan to end at start of next day
+       if ! scriptTTL="$(timeUntilNextDay)"; then
+           if [[ "$scriptTTL" -eq 0 ]]; then
+           ((scriptTTL++)); # Add 1 because 0 would cause 'timeout' to never timeout.
+           else
+           yell "ERROR: timeUntilNextDay exit code $?"; exit 1;
+           fi;
+       fi;
+    elif [[ "$ARG1" = "hour" ]]; then
+       # Set script lifespan to end at start of next hour
+       if ! scriptTTL="$(timeUntilNextHour)"; then
+           if [[ "$scriptTTL" -eq 0 ]]; then
+               ((scriptTTL++)); # Add 1 because 0 would cause 'timeout' to never timeout.
+           else
+               yell "ERROR: timeUntilNextHour exit code $?"; exit 1;
+           fi;
+       fi;
+    else
+       yell "ERROR:Invalid argument for setScriptTTL function."; exit 1;
+    fi
+} # Seconds until next (day|hour).
+checkMakeTar() {
+    # Desc: Checks that a valid tar archive exists, creates one otherwise
+    # Usage: checkMakeTar [ path ]
+    # Version: 1.0.1
+    # Input: arg1: path of tar archive
+    # Output: exit code 0 : tar readable
+    #         exit code 1 : tar missing; created
+    #         exit code 2 : tar not readable; moved; replaced
+    # Depends: try, tar, date
+    local PATH_TAR returnFlag0 returnFlag1 returnFlag2
+    PATH_TAR="$1"
+
+    # Check if file is a valid tar archive
+    if tar --list --file="$PATH_TAR" 1>/dev/null 2>&1; then
+       ## T1: return success
+       returnFlag0="tar valid";
+    else
+       ## F1: Check if file exists
+       if [[ -f "$PATH_TAR" ]]; then
+           ### T: Rename file
+           try mv "$PATH_TAR" "$PATH_TAR""--broken--""$(date +%Y%m%dT%H%M%S)" && \
+               returnFlag1="tar moved";
+       else
+           ### F: -
+           :
+       fi
+       ## F2: Create tar archive, return 0
+       try tar --create --file="$PATH_TAR" --files-from=/dev/null && \
+           returnFlag2="tar created";
+    fi
+    
+    # Determine function return code
+    if [[ "$returnFlag0" = "tar valid" ]]; then
+       return 0;
+    elif [[ "$returnFlag2" = "tar created" ]] && ! [[ "$returnFlag1" = "tar moved" ]]; then
+       return 1; # tar missing so created
+    elif [[ "$returnFlag2" = "tar created" ]] && [[ "$returnFlag1" = "tar moved" ]]; then
+       return 2; # tar not readable so moved; replaced
+    fi
+} # checks if arg1 is tar; creates one otherwise
+appendArgTar(){
+    # Desc: Writes first argument to temporary file with arguments as options, then appends file to tar
+    # Usage: appendArgTar "$(echo "Data to be written.")" [name of file to be inserted] [tar path] [temp dir] ([cmd1] [cmd2] [cmd3] [cmd4]...)
+    # Version: 1.0.3
+    # Input: arg1: data to be written
+    #        arg2: file name of file to be inserted into tar
+    #        arg3: tar archive path (must exist first)
+    #        arg4: temporary working dir
+    #        arg5+: command strings (ex: "gpsbabel -i nmea -f - -o kml -F - ")
+    # Output: file written to disk
+    # Example: decrypt multiple large files in parallel
+    #          appendArgTar "$(cat /tmp/largefile1.gpg)" "largefile1" $HOME/archive.tar /tmp "gpg --decrypt" &
+    #          appendArgTar "$(cat /tmp/largefile2.gpg)" "largefile2" $HOME/archive.tar /tmp "gpg --decrypt" &
+    #          appendArgTar "$(cat /tmp/largefile3.gpg)" "largefile3" $HOME/archive.tar /tmp "gpg --decrypt" &
+    # Depends: bash 5
+    # Ref/Attrib: Using 'eval' to construct command strings https://askubuntu.com/a/476533
+
+    # Save function name
+    local FN="${FUNCNAME[0]}";
+    #yell "DEBUG:STATUS:$FN:Finished appendArgTar()."
+    
+    # Set file name
+    if ! [ -z "$2" ]; then FILENAME="$2"; else yell "ERROR:$FN:Not enough arguments."; exit 1; fi
+    
+    # Check tar path is a file
+    if [ -f "$3" ]; then TAR_PATH="$3"; else yell "ERROR:$FN:Tar archive arg not a file."; exit 1; fi