1

I have created a script that smartd daemon (smartmontools) executes as per command below.

DEVICESCAN -a -m email -M test -M exec /usr/share/smartmontools/my-script -n stand...

Smartd appears to be running as root looking at the top command output but it fails to find a config file in /root. $USER, $HOME, whoami, export USER=$(id -u -n) commands do not echo anything, not even an empty line. When executed manually in terminal it prints the current username as expected. Script was chmod'ed to 700.

Why is this happening?

Edit: Here is the actual script that I want to run.

#!/bin/sh

export USER=$(id -u -n)
echo $whoami
echo "USER: "
echo "$USER"
echo $HOME

EMAIL_EXEC="mailx"
EMAIL_ACCOUNT="gmail"
EMAIL_SUBJECT="simplified"
EMAIL_BODY="simplified"

echo "$EMAIL_BODY " | $EMAIL_EXEC -A $EMAIL_ACCOUNT -s "$EMAIL_SUBJECT" email@gmail.com

After restarting smartd errors are found in the log and no email is sent unlike if executed manually as root.

sudo systemctl restart smartd
journalctl -u smartd

Here is the output of journalctl log:

Test of /etc/smartmontools/run.d/email to email@gmail.com produced unexpected output (69 bytes) to STDOUT/STDERR:
USER:
root
Account `gmail' does not exist.
No mail for root

export USER=$(id -u -n) appears to have set the $USER variable as you mentioned. "gmail" is a profile in /root/.mailrc file. Same error is produced when running as non-root user because the .mailrc file is missing in users home.

How can I set the $HOME variable like the $USER variable? That might give an idea why it's not finding the file.

DominicM
  • 669
  • Looked at the link, but unfortunately no alternatives to $USER variable produced different output. – DominicM Mar 07 '15 at 13:28
  • 1
    The USER variable is set by the login program. Daemons don't have it in their environment. If your script needs to know the userid it's running as, one thing it can do is run the id command. – Mark Plotnick Mar 07 '15 at 13:49
  • In particular, export USER=$(id -u -n) – Mark Plotnick Mar 07 '15 at 13:59
  • @MarkPlotnick that sounds like an answer, why not post it as one? – terdon Mar 07 '15 at 14:25
  • @terdon I can only answer one of his questions (and that question is basically a duplicate). I don't know why whoami would be printing nothing. – Mark Plotnick Mar 07 '15 at 15:06
  • The reason I am using $USER is to determine what user the daemon is running under. I don't actually need to know the user as long as it is running as root but it doesn't appear to run as root. The real script fails because it cannot find the config file in the root's home. "export USER=$(id -u -n)" command prints nothing same like $HOME variable. I am assuming that the reason my script fails is the same as why I can't get the user variable printed. – DominicM Mar 07 '15 at 15:21
  • @DominicM running a script as a user and running a command as a user are very different. The first runs in a non-interactive shell while the second runs in an interactive one. The two types of shell behave very differently. Please [edit] your question and explain the whole situation. – terdon Mar 07 '15 at 15:24
  • @terdon I simplified / clarified the question in the edit. I am not very familiar with shell scripting so I would like to hear more on how shell differs in interactive and non-interactive modes. – DominicM Mar 07 '15 at 15:33
  • 1
    export USER=$(id -u -n) won't produce any output, but it will set the USER variable. Can you show us the code that is not working, for example, the code that tries to read the config file? – Mark Plotnick Mar 07 '15 at 20:27
  • Sure, see edit. – DominicM Mar 08 '15 at 07:51
  • 1
    Try adding export HOME=~ . It's odd that mailx doesn't read /root/.mailrc. It does on opensuse, even when HOME is not set. I'll have to install arch to see why. – Mark Plotnick Mar 09 '15 at 07:54
  • echo $whoami in your script will echo a blank line because whoami is not normally a variable. It is a standard command, though. whoami or echo $(whoami) should output a username. – Mark Plotnick Mar 09 '15 at 07:57
  • @MarkPlotnick export HOME=~ printed "/root" and that actually fixed the problem completely! :) echo whoami just printed the literal string but echo $(whoami) printed the username, is that expected behavior? In any case I would love to know why variables are not being set on Arch Linux when executed by smartd, also are there any alternative fixes? – DominicM Mar 09 '15 at 09:41
  • Just a line whoami - no echo, no $ - should print the username. The absence of $HOME is probably an issue with systemd, and the particular version of mailx you have made it kind of a unique problem. – Mark Plotnick Mar 09 '15 at 10:18

1 Answers1

2

Your ultimate problem was that mailx, when called from a shell script run by smartd, started by systemd, on Arch Linux, was not reading the root user's $HOME/.mailrc file.

This was caused by a few factors:

  • The mailx on Arch Linux, s-nail, relies on the environment variable HOME when looking for the .mailrc file. If HOME isn't present, it uses the current working directory.
  if ((cp = getenv("HOME")) == NULL)
      cp = "."; /* XXX User and Login objects; Login: pw->pw_dir */
  homedir = savestr(cp); 

$USER, $LOGNAME, $HOME, $SHELL

User name (twice), home directory, and the login shell. The variables are set for the units that have User= set, which includes user systemd instances.

Since there was no HOME variable in the environment provided to smartd, and it was likely started in the / directory, mailx didn't read the /root/.mailrc file.

To fix: add the line

export HOME=~

or

export MAILRC=~/.mailrc

to the shell script before it invokes mailx

or (not tested by me) add

User=root

to the [Service] stanza of your smartd.service unit configuration file.

Mark Plotnick
  • 25,413
  • 3
  • 64
  • 82