0

I want to perform certain action (run another command) for every command that fail from user input.

Imagine you open a terminal and type:

git clone somewebsiteijustmadeup.org.edu.gov.de

and it fails (returns non-zero code). I would like to trigger another command after that.

Is there an easy way to do it without changing shell and recompiling it? I tried to find some information about it but internet gave me void.

Thanks :- )

----- EDIT

This is supposed to be done automatically by shell. No explicit command should be required to be typed by user. This should be sort of a default way to handle non-zero status of a any command.

Proko
  • 1,871
  • 1
  • 11
  • 23
  • How about `git clone somewebsiteijustmadeup.org.edu.gov.de || some_other_command` – whydoubt Sep 10 '19 at 21:11
  • Oh I see, I should make my question more precise. I don't want to type this explicitly. This is supposed to be triggered autmoatically – Proko Sep 10 '19 at 21:12
  • @0x5453 not in a script – Proko Sep 10 '19 at 21:18
  • @Proko It should work for interactive sessions as well. – 0x5453 Sep 10 '19 at 21:32
  • @0x5453 how would I wrap _any_ command with _any_ non-zero return code with trap? – Proko Sep 10 '19 at 21:37
  • 2
    Run for example `trap 'echo error detected' ERR` in the shell. Then `false` or other command that returns non zero and see. – Dzienny Sep 10 '19 at 21:39
  • @Dzienny this is a very specific command, and I want to do this for _any_ command without explicitly typing trap every time. This should be behavior coming out the shell itself, not from the user – Proko Sep 10 '19 at 21:44
  • You can add the `trap` to [the startup file](https://superuser.com/questions/183870/difference-between-bashrc-and-bash-profile), so that it runs when bash starts. – Dzienny Sep 10 '19 at 21:49
  • 1
    @Proko, generally, you can't distinguish between errors and programs that successfully exit with a false-y status. That is, if you take an action on any/every nonzero exit, `if [ -e somefile ]; then foo; else bar; fi` will always run your action before `bar`. That's (part of) why `set -e` / ERR traps have a huge list of caveats and exceptions, one that varies between individual shell releases. – Charles Duffy Sep 10 '19 at 21:51
  • @Dzienny sure, but how to wrap it around any command? running trap without argument resets all the signals so it seems like trap is not a way to go – Proko Sep 10 '19 at 21:52
  • 1
    Once again -- you can't, and shouldn't try; it's innately prone to failure. See [BashFAQ #105](http://mywiki.wooledge.org/BashFAQ/105#Exercises) for discussion. You want to run an arithmetic expression? Guess what, if it calculates a 0, that's treated as a "failure" (in some shell versions, but not others). You have code hidden inside a function? Whether its errors are considered "handled" (branched on) depends not just on the function's contents, but also on how that function is called. Etc, etc, etc. – Charles Duffy Sep 10 '19 at 21:53
  • https://www.in-ulm.de/~mascheck/various/set-e/ goes further in to how different shells handle corner cases. As you can see, there are a *lot* of corner cases, and is also a great deal of variance in their handling. – Charles Duffy Sep 10 '19 at 21:54
  • 1
    ...and, well, *is* `[ -s somefile ]` returning `1` an "error", if `somefile` does not exist? It successfully did the thing it was told to do (checking if `somefile` exists and is nonempty). Because POSIX-family shells (and, more general, the UNIX process model as a whole) use the same channel for successfully distinguishing between truthy/falsey results and between erroneous and non-erroneous exits, *correctly distinguishing only those exit statuses that relate to errors simply cannot be done* without explicit indication of user intent. – Charles Duffy Sep 10 '19 at 21:59
  • ...that said, "someone could reset it" seems a rather weak reason not to use `trap` -- someone could change *any* runtime configuration, unless you had a trapdoor involved in its establishment making that configuration impossible to modify or repeal. Which is doable, I suppose -- create a `DEBUG` trap that cancels any commands that might change your `ERR` trap (or the `DEBUG` trap itself), but... eww. – Charles Duffy Sep 10 '19 at 22:02
  • @CharlesDuffy wow that's actually super twisted. Didn't know about it, thanks. :) However, for me it does not matter if non-zero exit is an error or a command that "did its job" but there were some problems along the way like with the example of an attempt to open non-existing file and returned non zero code. For me this is an indication that something went wrong anyway. So as long as I am sure that only 0 status is ok, I still want to know if this is possible to do it. Hope you don;t mind my stubbornness :) – Proko Sep 10 '19 at 22:11
  • 1
    Gotcha. So long as the caveats of when `set -e` and `ERR` traps work (as described in the above links) are acceptable to you, use an ERR trap. If they're not -- SO is explicit to *software development*; if you're trying to configure interactive shells, you might consider [unix.se]. That said, specifically, if you're focusing on interactive shells *and you care whether a complete interactively-entered command line succeeded*, might you consider checking `$?` either while the prompt is being printed or in the `PROMPT_COMMAND` hook? – Charles Duffy Sep 10 '19 at 22:15
  • @CharlesDuffy sounds good, thanks for the help :) – Proko Sep 10 '19 at 22:22

0 Answers0