Group Members and Sound in Slackware's atd Daemon

10:55 Wed, 04 Apr 2012

Slackware's atd daemon won't play sound. The problem is a broken group file.

At is a system daemon that lets you run something at a time or date in the future. It differs from cron in that it is designed for one-offs. You don't have to edit a complex file as in crontab; you simply issue a command like at now + 30 minutes. It is perfect for things like reminders, which is what I use it for most of the time.

One of the things you want in a reminder is some sort of notification to alert you (obviously). Typically, a sound plays and a notice pops up to tell you about the reminder.

It is such a common use case that I wrote a simple shell script to do just that. It uses aplay to play the sound and zenity (you could use gxmessage or xmessage) to pop up a simple text box.

However, ever since I set it up a couple of years ago, sound has never worked when I ran it via at, which pretty much defeated the purpose of the thing.

The symptoms were a bunch of errors (in the email I get from at's output) such as these:

ALSA lib confmisc.c:768:(parse_card) cannot find card '0'
ALSA lib conf.c:4184:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
ALSA lib conf.c:4184:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1251:(snd_func_refer) error evaluating name
ALSA lib conf.c:4184:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:4663:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2212:(snd_pcm_open_noupdate) Unknown PCM default

I put these errors verbatim for google to index so anyone else with this problem can find it.

I checked all the permissions and ownerships and everything seemed ok. In the end, I gave up.

Today, with gritted teeth and girded loins(!), I got stuck into it. It works fine when run as root or through sudo. It must be something to do with permissions. Time to google.

Finally, a throwaway comment in a VectorLinux forum provided a clue. The user did not have his name as a member of the audio group.

But, I am a member of the audio group, as the groups command tells me:

users lp wheel floppy audio video cdrom plugdev power scanner burning

In a moment of inspiration, I checked the contents of /etc/group. That's odd, I don't appear as a member of audio. A bit more checking and it turns out I don't appear as a member for a bunch of groups (video, cdrom, scanner), notwithstanding anything that the groups command might tell me. It is clear that the group file (or perhaps gshadow) is out of sync with whatever database the groups command references.

I used gpasswd to add myself to each of the missing groups. (I noticed this had the side effect of also changing /etc/gshadow, which previously had been empty.)

Success. My alert script now plays a sound and pops up a text box. Hooray.

To recap: something somewhere is broken. The symptoms were that me, the user, could play a sound, but that at (running as a command initiated by me) could not. Both root and at running from root could play a sound.

If I had to take a guess, I would say that the interactive shell permissions were ok, but that at is checked against either /etc/group or /etc/gshadow. How that would happen is something I shall investigate later.

Addendum

I think I've figured it out, thanks to a little help at Linux Questions. Slackware automatically adds a console user to the groups defined in /etc/login.defs. Since at runs the command in a separate shell, I am guessing that that shell is not defined as a login shell (which makes sense), so the user is not in those groups when the command runs.

The answer is to do what I did and manually add the user to the groups, although, instead of using gpasswd you can use the vigr editor (which I did not know about) as root to edit /etc/group directly.

[    Sidenote
One of the strangest design decisions in at is that it is interactive. There is no way to specify on the command line what you want to run. For example, sed lets you specify its commands on the command line with the -e switch, as in sed -e 's/foo/bar/g' file. At doesn't let you do that. It drops you into a shell in which you type the commands you want. This means you can't use it in a script. As I said, it is a strange design; I have never wanted to issue more than one command at a time (where a shell makes sense), but have many, many times wanted to use at within a script.

Of course, it is relatively trivial to work around with something like echo "some_command" | at now + 2 days or at now + 2 days <<< "some_command". ]

Categories: unix

Leave a comment

Your email address will not be published. Required fields are marked *

Plain text only please, any < or > are removed.