Portably trapping ERR in shell script
Asked Answered
T

2

10

I'm trying to write a shell script that aborts when a command fails and displays the offending line number.

set -e
trap 'echo "$0 FAILED at line ${LINENO}"' ERR

Turned out the trap line does not work with Ubuntu's default shell script interpreter, dash. If I change the shebang line to #!/bin/bash this works but not with #!/bin/sh. Is there a way to make this work without relying on bash being present?

By the way, The error I get from dash is this:

trap: ERR: bad trap
Thecla answered 9/7, 2015 at 9:22 Comment(0)
T
10

You can trap on exit and test the exit code like this:

set -e
trap '[ $? -eq 0 ] && exit 0 || echo "$0 FAILED at line ${LINENO}"' EXIT
Terrellterrena answered 9/10, 2019 at 5:19 Comment(6)
The line number doesn't seem to work without bash though. Not for me at least.Thecla
Seems that $LINENO is not available in dash. wiki.ubuntu.com/DashAsBinSh#A.24LINENOTerrellterrena
So it is supported in dash but debian builds the package with --disable-lineno flag. They do this because autoconf would select dash as the shell to use and that causes many other packages to fail to install properly. bugs.debian.org/cgi-bin/bugreport.cgi?bug=582952Terrellterrena
Interesting. So from what I gather, LINENO is indeed part of POSIX so you could say using it is portable (hence the question requirement is met), on the other hand looks like what lots of people have on their machines has it disabled. I don't know what the situation is on other shells and I'm still unsure whether I should switch the accepted answer...Thecla
Having thought a bit more about this, since the currently accepted answer does not provide an alternative, I'll switch to yours.Thecla
dash-0.5.11.5-2.fc37.x86_64 on Fedora has LINENO enabled, but I'm seeing dash print the line number within the trap string (1 unless you write it multiline), not of the line that caused EXIT 🙅. Makes this pretty useless compared to set -e. EXIT also has "false positives" when script is deliberately exiting non-0 in a way that's not a bug...Harriette
G
7

According to various sources on the internets, ERR is not standard at all and only supported by the Korn Shell - which seemed to invent it - and Bash, which seemed to adopt it. https://github.com/bmizerany/roundup/issues/25#issuecomment-10978764

I would go for the easy solution.

Simply change

#!/bin/sh

to

#!/bin/bash

or better

#!/usr/bin/env bash
Grandmotherly answered 25/7, 2015 at 18:49 Comment(1)
That's how I did it in the end. Not exactly an answer to my question but since you provide a source for it not being possible, I'm accepting it. Thank you.Thecla

© 2022 - 2024 — McMap. All rights reserved.