F566
F566

Reputation: 625

How to control the exit order in Linux command pipe?

My script:

./app 2&>1 | ./pipelog --filename=run.log

I use pipelog to rotate app's stdout、stderr log.

I tested it, when send SIGTERM to the script during shutdown, two processes receive the signal at the same time:

The resulting problem is that the last log of the app is gone.

How to implement pipelog to exit after the app exits?

I can only sleep in the pipelog for a fixed amount of time now, which is not elegant.

Upvotes: 1

Views: 214

Answers (1)

This will probably work:

./app 2&>1 | (trap '' TERM; exec ./pipelog --filename=run.log)

With that, pipelog should ignore SIGTERM and keep running until it gets to EOF on its input pipe, which will happen once app exits.

I assume app and pipelog are both in-house programs, so I can't be totally sure this will work, but here's a few failure cases I can think of and what to do about them:

  1. If app starts daemonized children that share its stdout or stderr, but don't shut down when it does, then they'll keep pipelog alive indefinitely. If this is the case, and you can't fix it in app, then a solution will probably involve a wrapper program that uses PR_SET_CHILD_SUBREAPER.
  2. If pipelog doesn't exit on EOF, then it will stay alive indefinitely. Any workaround to this would inherently involve a race condition, so if it's the case, you should fix it in pipelog's code.
  3. If pipelog sets a signal handler for SIGTERM, it will override the trap above and keep doing what it used to do. If this is the case and you can't disable that, then a solution will probably involve trapping SIGTERM in the outer bash script and manually sending it to only app.

Upvotes: 2

Related Questions