On Thu, 17 Jan 2019 09:41:26 +0100 Johannes 'josch' Schauer <jo...@debian.org> 
wrote:
> please correct me if I'm wrong but could annotate-output not be greatly
> simplified by using this proof-of-concept:
> 
>       handler () {
>               while IFS= read -r line || [ -n "$line" ]; do
>                       printf "%s %s: %s\n" "$(date --iso-8601=seconds)" "$1" 
> "$line"
>               done
>       }
>       
>       { "$@" 2>&1 1>&3 3>&- | handler E; } 3>&1 1>&2 | handler O
> 
> So the script would loose some complexity and would not have as much
> stuff in the background anymore like processes and temporary files it
> needs to clean up. It could:
> 
>  - remove cleanup exit trap
>  - no temporary directory
>  - no temporary fifos
>  - no background processes to start and cleanup
> 
> Am I missing an obvious reasons why fifos are used instead?

Yes I was. The original annotate-output outputs stdout as well as stderr to
stdout while the above outputs annotations to stdout to stdout and annotations
to stderr to stderr. Furthermore, the above is unable to capture the exit
status.

Fortunately, with one additional file descriptor it is possible to restore the
behaviour of the original annotate-output. Full script attached.

Thanks!

cheers, josch
#!/bin/sh

# Copyright 2019 Johannes 'josch' Schauer <jo...@mister-muffin.de>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.

set -eu

usage ()
{
	echo \
"Usage: $progname [options] program [args ...]
  Run program and annotate STDOUT/STDERR with a timestamp.

  Options:
   +FORMAT    - Controls the timestamp format as per date(1)
   -h, --help - Show this message"
}

FMT="+%H:%M:%S"
while [ "$1" ]; do
	case "$1" in
	+*)
		FMT="$1"
		shift
		;;
	-h|-help|--help)
		usage
		exit 0
		;;
	*)
		break
		;;
	esac
done

if [ $# -lt 1 ]; then
	usage
	exit 1
fi

handler () {
	while IFS= read -r line || [ -n "$line" ]; do
		printf "%s %s: %s\n" "$(date "$FMT")" "$1" "$line"
	done
}

echo "Started $@" | handler I

err=0
{ { { { {
          "$@" 2>&1 1>&4 3>&- 4>&-; echo $? >&2;
        } | handler E >&3;
      } 4>&1 | handler O >&3;
    } 2>&1;
  } | { read xs; exit $xs; };
} 3>&1 || err=$?

echo "Finished with exitcode $err" | handler I
exit $err

Attachment: signature.asc
Description: signature

Reply via email to