Reputation: 5584
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
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