Yes, &>
is a bash
operator (now also supported by zsh
, while zsh
always had >&
for the same like in csh
), and >(...)
a ksh
operator (now also supported by zsh
and bash
), neither are sh
operator. That unquoted $LOG_FILE where you obviously don't want split+glob here, makes it zsh syntax (the only one of those shells where split+glob is not performed implicitly upon unquoted expansions, though in zsh
, you'd just do exec >&1 > $LOG_FILE 2>&1
).
In sh
syntax, you can do:
#! /bin/sh -
LOG_FILE="/tmp/abc.log"
{
# your script here
} 2>&1 | tee -- "$LOG_FILE"
Or put everything in a function:
#! /bin/sh -
LOG_FILE="/tmp/abc.log"
main() {
# your script here
}
main "$@" 2>&1 | tee -- "$LOG_FILE"
In any case, both that and your zsh
-style approach would end up printing error messages on the same resource as open on stdout. So if someone does your-script > out 2> err
, err
will be empty and out
will contain both the normal output and the errors.
To make sure the original destination of output and error is preserved, you could do instead:
{
{
main "$@" 3>&- | tee -a -- "$LOG_FILE" >&3 3>&-
} 2>&1 | tee -a -- "$LOG_FILE" >&2 3>&-
} 3> "$LOG_FILE" 3>&1
(untested).