Created
December 9, 2009 21:50
-
-
Save jollyroger/252866 to your computer and use it in GitHub Desktop.
"Fork, aggregate, log" script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# NAME | |
# fal - wrapper script to run several concurrent commands and gather their | |
# output into one log file. fal is an abbreviation for "fork, aggregate, log" | |
# | |
# SYNOPSIS | |
# fal -c count [-l logfile] [-t] [-p pipe] [--] command [command_args] | |
# | |
# OPTIONS | |
# -c count | |
# Run command concurrently count times. | |
# | |
# -l logfile | |
# Store logs to the logfile. By default logfile is stored in current | |
# directory and called the same as the command to run but with ".log" | |
# extension. If such file exists, the output will be attached to the end | |
# of the file. | |
# | |
# -p pipe | |
# Create named pipe for aggregating stdout of processes. By default file | |
# is called command.pipe | |
# | |
# -t | |
# write output to both logfile and stdout | |
# | |
# The command will be run in a subshell with its arguments. If for some reason | |
# arguments are similar to those accepted by this script, use "--" to separate | |
# fal arguments and command to be run. | |
print_usage() | |
{ | |
echo "Usage: $0 -c count [-l logfile] [-p pipe] [--] command [command_args]" >&2 | |
exit 1; | |
} | |
# Parsing arguments | |
if [ "$#" -lt 3 ] ; then | |
print_usage; | |
fi | |
set -- `getopt "c:l:p:t" "$@"` | |
while [ ! -z "$1" ] | |
do | |
case $1 in | |
-c) COUNT=$2 ;; | |
-l) LOG_FILENAME=$2 ;; | |
-p) PIPE_FILENAME=$2 ;; | |
-t) ENABLE_STDOUT=1 ;; | |
--) break ;; | |
esac | |
shift | |
done | |
# Check variables and set default settings if needed | |
COMMAND_STRING=$@ | |
COMMAND_STRING=${COMMAND_STRING#*-- } | |
COMMAND=${COMMAND_STRING%% *} | |
if [ -z "$COUNT" ] ; then | |
print_usage; | |
fi | |
if [ -z "$LOG_FILENAME" ] ; then | |
LOG_FILENAME="$COMMAND.log" | |
fi | |
if [ -z "$PIPE_FILENAME" ] ; then | |
PIPE_FILENAME="$COMMAND.pipe" | |
fi | |
# Some debugging info before actual work. | |
#echo "ARGV = $@" | |
#echo "COMMAND_STRING = $COMMAND_STRING" | |
#echo "COMMAND = $COMMAND" | |
#echo "LOG_FILENAME = $LOG_FILENAME" | |
#echo "PIPE_FILENAME = $PIPE_FILENAME" | |
#echo "COUNT = $COUNT" | |
if [ ! -p $PIPE_FILENAME ] ; then | |
mkfifo $PIPE_FILENAME | |
fi | |
for ((i=1 ; i <= COUNT ; i++ )) | |
do | |
eval $COMMAND_STRING >$PIPE_FILENAME 2>$PIPE_FILENAME & | |
done | |
# The next command will never exit until all PIDs who feed the pipe exit. After, | |
# command will exit with "broken pipe" message which will be suppressed. | |
if [ -z "$ENABLE_STDOUT" ] ; then | |
cat $PIPE_FILENAME >> $LOG_FILENAME 2>/dev/null | |
else | |
cat $PIPE_FILENAME | tee $LOG_FILENAME | |
fi | |
# Cleaning up before exit | |
rm $PIPE_FILENAME | |
exit 0; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment