Live data from Hacker News

“Exit traps” can make your Bash scripts more robust and reliable (2013)

redsymbol.net

31–40 of 159 posts

Re: “Exit traps” can make your Bash scripts more robust and reliable (2013)

#31
post #11

I used an exit trap to kill an SSH agent that I am running, and I noticed that dash did not kill if the script was interrupted, but only if it ran to successful completion. I asked on the mailing list if this was expected behavior, and it turns out that POSIX only requires EXIT to run on a clean shutdown; to catch interruptions, add more signals. trap 'eval $(ssh-agent -k)' EXIT INT ABRT KILL TERM

You can't trap kill can you? doesn't that just go kill your process without any possibility of intervention or other actions? Also you probably want to handle HUP there too I would think (depending on what the script does)

SIGABRT would have to come from the process itself; IDK when if ever the shell would do that.

And SIGKILL can't be handled, so that is indeed pointless.

Re: “Exit traps” can make your Bash scripts more robust and reliable (2013)

#32

I wish there was a nicer shell scripting language that simply transpiled to Bash and would generate all this boilerplate code for me. There is https://batsh.org/ which has a nice syntax but it doesn't even support pipes or redirection, making it pretty worthless for shell scripting. I haven't found any other such scripting languages.

What's the difference between that and Go?

Re: “Exit traps” can make your Bash scripts more robust and reliable (2013)

#33
post #11

I used an exit trap to kill an SSH agent that I am running, and I noticed that dash did not kill if the script was interrupted, but only if it ran to successful completion. I asked on the mailing list if this was expected behavior, and it turns out that POSIX only requires EXIT to run on a clean shutdown; to catch interruptions, add more signals. trap 'eval $(ssh-agent -k)' EXIT INT ABRT KILL TERM

I think you want:

  trap 'ssh-agent -k' EXIT INT TERM
I don't see any reason for the eval as "ssh-agent -k" doesn't return anything useful you want the shell to evaluate.

Re: “Exit traps” can make your Bash scripts more robust and reliable (2013)

#34

Earlier quoted context omitted.

You can't trap kill can you? doesn't that just go kill your process without any possibility of intervention or other actions? Also you probably want to handle HUP there too I would think (depending on what the script does)

SIGABRT would have to come from the process itself; IDK when if ever the shell would do that. And SIGKILL can't be handled, so that is indeed pointless.

POSIX says that "setting a trap for SIGKILL or SIGSTOP produces undefined results", but for signals it describes SIGKILL as "Kill (cannot be caught or ignored)".

I'm guessing this is some relic from 80s Unix systems where SIGKILL behaved different, or perhaps just an inconsistency/oversight.

Re: “Exit traps” can make your Bash scripts more robust and reliable (2013)

#36
post #25
post #7

An annoying thing about bash is that EXIT will also run on SIGINT (^C), which most other shells won't (in my reading it's also not POSIX compliant, although the document is a bit vague). Some might argue this is a feature, but IMHO it's a bug – sometimes you really don't want cleanup to happen so people can inspect the contents of temporary files for debugging. Because trap doesn't pass the signal information to the…

Some temporary file remover. Lol indeed

// Thinks about that type I typed rm -rf /something by mistake.

It took a few seconds before I thought... "Why does it take that long for only a handful of files?"

I never did that again.

Had my DOS filesystem mounted under Linux too (yes that long ago), and I spent a few days guessing the first letter of each deleted file with norton disk doctor or undeleter or something. That was fun (FAT16 filesystems overwrote the first letter of each filename to delete it)

At least it wasn't a mistake I made at work on some production thing. Though there is a reason I make all the desktops on windows production servers bright red. One time I was tired and shut down "my laptop" forgetting I was still logged into a remote server 200km away..... :/ Of course the iLO wasn't hooked up but I was extremely happy to find that HP servers listen to wake on LAN even when they're off. Another one for the never again books :P

Re: “Exit traps” can make your Bash scripts more robust and reliable (2013)

#38
>The secret sauce is a pseudo-signal provided by bash, called EXIT, that you can trap; commands or functions trapped on it will execute when the script exits for any reason.

"Secret Sauce", why is this secret at all.

Nothing against the author who's helping the ecosystem here, but is there an authoritative guide on Bash that anyone can recommend?

Hopefully something that's portable between Mac & Linux.

The web is full of contradictory guides and shellcheck seems to be the last line of defense.

- https://github.com/koalaman/shellcheck

Re: “Exit traps” can make your Bash scripts more robust and reliable (2013)

#39
post #7

An annoying thing about bash is that EXIT will also run on SIGINT (^C), which most other shells won't (in my reading it's also not POSIX compliant, although the document is a bit vague). Some might argue this is a feature, but IMHO it's a bug – sometimes you really don't want cleanup to happen so people can inspect the contents of temporary files for debugging. Because trap doesn't pass the signal information to the…

> Because trap doesn't pass the signal information to the handler

You can examine $? on entry to the trap function. On signals, it will be 128 + signal. i.e. on TERM (15) it will be 143. On INT (2) it will be 130.

  #!/bin/bash

  skip_exit=
  on_exit() {
    code=$?
    if test $code == 130; then
      skip_exit=1
    fi
    if test -n "$skip_exit"; then
      return
    fi
    echo "Exiting with: $code"
    return $code
  }

  trap on_exit INT EXIT

  sleep 2
  false
With ctrl-c:

  $ ./foo.sh
  ^C
After 2 seconds:

  $ ./foo.sh
  Exiting with: 1
You can also setup separate handlers for each signal and use a sentinel:

  $ cat foo.sh
  #!/bin/bash
  
  skip_exit=
  
  on_int() {
    echo int
    skip_exit=1
  }
  
  on_exit() {
    test -n "$skip_exit" && return
    echo exit
  }
  
  
  trap on_int INT
  trap on_exit EXIT
  
  sleep 2
With ctrl-c:

  $ ./foo.sh
  ^Cint
After 2 seconds: $ ./foo.sh exit

Re: “Exit traps” can make your Bash scripts more robust and reliable (2013)

#40

I wish there was a nicer shell scripting language that simply transpiled to Bash and would generate all this boilerplate code for me. There is https://batsh.org/ which has a nice syntax but it doesn't even support pipes or redirection, making it pretty worthless for shell scripting. I haven't found any other such scripting languages.

What's the difference between that and Go?

Go doesnt seem related at all?
Post reply on HN