nrlakin
nrlakin

Reputation: 5584

Shell script doesn't exit if output redirected to logger

I was looking for a way to route the output of my shell scripts to syslog, and found this article, which suggests putting the following line at the top of the script:

exec 1> >(logger -s -t $(basename $0)) 2>&1

I've tried this with the following simple script:

#!/bin/bash
exec 1> >(logger -s -t $(basename $0)) 2>&1
echo "testing"
exit 0

When I run this script from the shell, I do indeed get the message in the syslog, but the script doesn't seem to return--in order to continue interacting with the shell, I need to hit Enter or send a SIGINT signal. What's going on here? FWIW, I'm mostly using this to log the results of cron jobs, so in the wild I probably don't need it to work properly in an interactive shell session, but I'm nervous using something I don't really understand in production. I am mostly worried about spawning a bunch of processes that don't terminate cleanly.

I've tested this on Ubuntu 15.10, Ubuntu 16.04, and OSX, all with the same result.

Upvotes: 2

Views: 1142

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 753805

Cutting a long story short: the shell script does exit and so does the logger — there isn't actually a problem — but the output from the logger lead to confusion.

Converting comments into an answer.

Superficially, given the symptoms you describe, what's going on is that Bash isn't exiting until all its child processes exit. You could try exec >/dev/null 2>&1 before exit 0 to see if that stops the logger — basically, the redirection closes its inputs, so it should terminate, allowing the script to exit.

However, when I try your script (bash logtest.sh) on macOS Sierra 10.12.2 (though I'd not expect it to change in earlier versions), the command exits promptly and produces a log message on the terminal like this (I use Osiris JL: as my prompt):

Osiris JL: bash logtest.sh
Osiris JL: Dec 26 12:23:50  logtest.sh[6623] <Notice>: testing

Osiris JL: ps
  PID TTY           TIME CMD
71792 ttys000    0:00.25 -bash
  534 ttys002    0:00.57 -bash
  543 ttys003    0:01.71 -bash
  558 ttys004    0:00.44 -bash
Osiris JL:

I hit return on the blank line and got the prompt before the ps command.

Note that the message from logger arrived after the prompt.

When I ran bash logtest.sh (where logtest.sh contained your script), the only key I hit was the return to enter the command (which the shell read before running the command). I then got a prompt, the output from logger, and a blank line with the terminal waiting for input. That's normal. The logger was not still running — I could check that in other windows.

Try typing ls instead of just hitting return. The shell is waiting for input. It wrote its prompt, but the logger output confused the on-screen layout. For me, I got:

Osiris JL: bash logtest.sh
Osiris JL: Dec 26 13:28:28  logtest.sh[7133] <Notice>: testing
ls
README.md               ix37.sql                mq13.c                  sh11.o
Safe                    lib                     mq13.dSYM               so-4018-8770
Untracked               ll89                    oddascevendesc          so-4018-8770.c
ci11                    ll89.cpp                oddascevendesc.c        so-4018-8770.dSYM
ci11.c                  ll89.dSYM               oddascevendesc.dSYM     sops
ci11.dSYM               ll97                    rav73                   src
data                    ll97.c                  rav73.c                 tf17
doc                     ll97.dSYM               rav73.dSYM              tf17.cpp
es.se-36764             logtest.sh              rd11                    tf17.dSYM
etc                     mac-clock-get-time      rd11.c                  tf19
fa37.sh                 mac-clock-get-time.c    rd11.dSYM               tf19.c
fileswap.sh             mac-clock-get-time.dSYM rn53                    tf19.dSYM
gm11                    makefile                rn53.c                  x-paste.c
gm11.c                  matrot13                rn53.dSYM               xc19
gm11.dSYM               matrot13.c              sh11                    xc19.c
inc                     matrot13.dSYM           sh11.c                  xc19.dSYM
infile                  mq13                    sh11.dSYM
Osiris JL:

Upvotes: 2

Related Questions