-
-
Save jstine35/e0fc0e06ec06d74bc3ebd67585bf2a1d to your computer and use it in GitHub Desktop.
# FIRST VERSION - Outputs UTS formatted timestamp. | |
# ------------------------------------------------------------------------------------- | |
# handy pipe redirect that appends a datestamp to every line of output. Just paste this into | |
# the top of a typical BASH script. Note that it outputs localtime due to limitations in | |
# BASH printf (whichis used for speed reasons). Automated runner processes as a rule of thumb | |
# should be set to UTC anyways, so it seems not a significant limitation. | |
s_datestamp() { | |
while IFS= read -r line; do | |
# by nature BASH might run process subst twice when using >&2 pipes. This is a lazy | |
# way to avoid dumping two timestamps on the same line: | |
if [[ "$line" =~ \[[0-9]{4}-[^[:space:]]*\] ]]; then | |
echo "$line" | |
else | |
printf "%(%Y-%m-%dT%H:%M:%S%z)T" "-1" | |
fi | |
done | |
} | |
exec 1> >(s_datestamp) | |
exec 2> >(s_datestamp) | |
# ------------------------------------------------------------------------------------- | |
# SECOND VERSION - Outputs time since the script started. | |
# ------------------------------------------------------------------------------------- | |
# handy pipe redirect that appends a datestamp to every line of output. Just paste this into | |
# the top of a typical BASH script. | |
procstarttime=$(date -u '+%s') | |
s_timestamp() { | |
while IFS= read -r line; do | |
curtime=$(date -u '+%s') | |
deltatime=$(( curtime - procstarttime )) | |
timestamp="$(printf "%03d:%02d" $(( deltatime / 60 )) $(( deltatime % 60 )))" | |
# by nature BASH might run process subst twice when using >&2 pipes. This is a lazy | |
# way to avoid dumping two timestamps on the same line: | |
if [[ "$line" != \[${timestamp%% *}* ]]; then | |
echo "[$timestamp] $line" | |
else | |
echo "$line" | |
fi | |
done | |
} | |
exec 1> >(s_timestamp) | |
exec 2> >(s_timestamp) | |
# ------------------------------------------------------------------------------------- | |
I'm experiencing an issue in which a failing process is not printing the last error message because of this trick. I'm guessing that the shell is configured with
set -o pipefail
andset -o errexit
by GitLab CI and the failure doesn't allows_timestamp
to run and echo the timestamp prefixed line. Any possible workarounds to allow the log to still go through?
That could be the case if the parent shell is also configuring set -E
(capital E), which enables inheritance of pipefail. Without -E
though the pipefail and errexit settings shouldn't be inherited by other scripts being run. However, you can add some code to the s_datestamp
function to be sure:
s_datestamp() {
local - # saves parent's settings, restores them when function returns
set +o pipefail +o errexit
trap - ERR # may need to clear other traps here...
[... rest of function as above ...]
}
The other (and more likely) possibility is that something is killing the entire process tree when the parent process exits. Whether or not that's the case, and how to work around it, would depend a bit on whether your runners are Windows or Linux based.
I'm experiencing an issue in which a failing process is not printing the last error message because of this trick. I'm guessing that the shell is configured with
set -o pipefail
andset -o errexit
by GitLab CI and the failure doesn't allows_timestamp
to run and echo the timestamp prefixed line.Any possible workarounds to allow the log to still go through?