140 lines
3.8 KiB
Bash
140 lines
3.8 KiB
Bash
|
#!/usr/bin/env bash
|
|||
|
##
|
|||
|
## BSD 3-Clause License
|
|||
|
##
|
|||
|
## This file is part of the Basalt project.
|
|||
|
## https://gitlab.com/VladyslavUsenko/basalt.git
|
|||
|
##
|
|||
|
## Copyright (c) 2019-2021, Vladyslav Usenko and Nikolaus Demmel.
|
|||
|
## All rights reserved.
|
|||
|
##
|
|||
|
|
|||
|
#
|
|||
|
# Usage:
|
|||
|
# list-jobs.sh DIRNAME [DIRNAME ...] [-s|--short] [-o|--only STATUS]
|
|||
|
#
|
|||
|
# Lists all batch jobs found in DIRNAME. If the optional argument
|
|||
|
# STATUS is passed, only lists jobs with that status. Multiple
|
|||
|
# statuses can be passed in a space-separated string.
|
|||
|
#
|
|||
|
# Possible status arguments: queued, running, completed, failed, unknown
|
|||
|
# You can also use 'active' as a synonym for 'queued running unknown'
|
|||
|
|
|||
|
# exit on error
|
|||
|
set -o errexit -o pipefail
|
|||
|
|
|||
|
|
|||
|
# we need GNU getopt...
|
|||
|
GETOPT=getopt
|
|||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|||
|
if [ -f /usr/local/opt/gnu-getopt/bin/getopt ]; then
|
|||
|
GETOPT="/usr/local/opt/gnu-getopt/bin/getopt"
|
|||
|
fi
|
|||
|
fi
|
|||
|
|
|||
|
# option parsing, see: https://stackoverflow.com/a/29754866/1813258
|
|||
|
usage() { echo "Usage: `basename $0` DIRNAME [DIRNAME ...] [-s|--short] [-o|--only STATUS]" ; exit 1; }
|
|||
|
|
|||
|
# -allow a command to fail with !’s side effect on errexit
|
|||
|
# -use return value from ${PIPESTATUS[0]}, because ! hosed $?
|
|||
|
! "$GETOPT" --test > /dev/null
|
|||
|
if [[ ${PIPESTATUS[0]} -ne 4 ]]; then
|
|||
|
echo 'I’m sorry, `getopt --test` failed in this environment.'
|
|||
|
exit 1
|
|||
|
fi
|
|||
|
|
|||
|
OPTIONS=hsjo:
|
|||
|
LONGOPTS=help,short,jobids,only:
|
|||
|
|
|||
|
# -regarding ! and PIPESTATUS see above
|
|||
|
# -temporarily store output to be able to check for errors
|
|||
|
# -activate quoting/enhanced mode (e.g. by writing out “--options”)
|
|||
|
# -pass arguments only via -- "$@" to separate them correctly
|
|||
|
! PARSED=$("$GETOPT" --options=$OPTIONS --longoptions=$LONGOPTS --name "`basename $0`" -- "$@")
|
|||
|
if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
|
|||
|
# e.g. return value is 1
|
|||
|
# then getopt has complained about wrong arguments to stdout
|
|||
|
usage
|
|||
|
fi
|
|||
|
# read getopt’s output this way to handle the quoting right:
|
|||
|
eval set -- "$PARSED"
|
|||
|
|
|||
|
SHORT=n
|
|||
|
ONLY=""
|
|||
|
JOBIDS=n
|
|||
|
# now enjoy the options in order and nicely split until we see --
|
|||
|
while true; do
|
|||
|
case "$1" in
|
|||
|
-h|--help) usage ;;
|
|||
|
-s|--short) SHORT=y; shift ;;
|
|||
|
-j|--jobids) JOBIDS=y; shift ;;
|
|||
|
-o|--only) ONLY="$2"; shift 2 ;;
|
|||
|
--) shift; break ;;
|
|||
|
*) echo "Programming error"; exit 3 ;;
|
|||
|
esac
|
|||
|
done
|
|||
|
|
|||
|
# handle non-option arguments --> directories
|
|||
|
if [[ $# -lt 1 ]]; then
|
|||
|
echo "Error: Pass at least one folder"
|
|||
|
usage
|
|||
|
fi
|
|||
|
DIRS=("$@")
|
|||
|
|
|||
|
# status aliases:
|
|||
|
ONLY="${ONLY/active/queued running unknown}"
|
|||
|
ONLY="${ONLY/notcompleted/queued running failed unknown}"
|
|||
|
|
|||
|
contains() {
|
|||
|
[[ $1 =~ (^| )$2($| ) ]] && return 0 || return 1
|
|||
|
}
|
|||
|
|
|||
|
display() {
|
|||
|
if [ -z "$ONLY" ] || contains "$ONLY" $2; then
|
|||
|
if [ $SHORT = y ]; then
|
|||
|
echo "$1"
|
|||
|
else
|
|||
|
echo -n "$1 : $2"
|
|||
|
if [ -n "$3" ]; then
|
|||
|
echo -n " - $3"
|
|||
|
fi
|
|||
|
echo ""
|
|||
|
fi
|
|||
|
fi
|
|||
|
}
|
|||
|
|
|||
|
for d in "${DIRS[@]}"; do
|
|||
|
for f in `find "$d" -name status.log | sort`; do
|
|||
|
DIR=`dirname "$f"`
|
|||
|
|
|||
|
# ignore backup folder from "rerun" scripts
|
|||
|
if [[ `basename $DIR` = results-backup* ]]; then
|
|||
|
continue
|
|||
|
fi
|
|||
|
|
|||
|
if ! grep Started "$f" > /dev/null; then
|
|||
|
display "$DIR" unknown "not started"
|
|||
|
continue
|
|||
|
fi
|
|||
|
|
|||
|
# job has started:
|
|||
|
|
|||
|
if grep Completed "$f" > /dev/null ; then
|
|||
|
display "$DIR" completed ""
|
|||
|
continue
|
|||
|
fi
|
|||
|
|
|||
|
# job has started, but not completed (cleanly)
|
|||
|
|
|||
|
# check signs of termination
|
|||
|
if [ -f "$DIR"/output.log ] && grep "Command terminated by signal" "$DIR"/output.log > /dev/null; then
|
|||
|
display "$DIR" failed killed "`grep -oP 'Command terminated by \Ksignal .+' "$DIR"/output.log`"
|
|||
|
continue
|
|||
|
fi
|
|||
|
|
|||
|
# might be running or aborted
|
|||
|
display "$DIR" unknown started
|
|||
|
|
|||
|
done
|
|||
|
done
|