I have a shell script that runs a clamav scan on a folder on my arch linux system and is supposed to email the results. Here's the code:

/usr/bin/clamscan -r -i /path/to/folder | /usr/bin/mailx -A gmail -s "Clam Scan Results $(/usr/bin/date +%F)" [email protected]

The above one-liner works fine if run on the bash command line and I confirmed that the account configured in /etc/mailrc works and email is received. But I want it to run on a schedule and I setup a systemd service unit to call a script called ~/bin/virusscan.sh and a systemd timer unit to trigger it at 2 AM every night. The mailx piece after the pipe is always reporting ... email not sent

Is there a significant difference in how SystemD executes the script?


Description=Daily virus scan




Description=Execute virus scan daily at 2 AM

OnCalendar=*-*-* 02:00:00


Then I can run the service imediatelly to test with:

sudo systemctl start virusscan 

And the status of the service while running is the following:

virusscan.service - Daily virus scan
   Loaded: loaded (/usr/lib/systemd/system/virusscan.service; disabled; vendor preset: disabled)
   Active: active (running) since Tue 2016-10-04 11:54:39 PDT; 11s ago
 Main PID: 29915 (virusscan.sh)
    Tasks: 4 (limit: 4915)
   CGroup: /system.slice/virusscan.service
           ├─29915 /bin/sh /home/username/bin/virusscan.sh
           ├─29920 /usr/bin/clamscan -r -i /path/to/folder/
           └─29921 /usr/bin/mailx -A gmail -s Clam Scan Results 2016-10-04 [email protected]

Oct 04 11:54:39 hurricane systemd[1]: Started Daily virus scan.

It looks like SystemD breaks the one liner in the script into separate processes and also it expands the string that is supposed to be the subject line of the message and removes the quotes ... That could be the problem, perhaps, and I just need to escape it properly ... Then when the service unit is done running, I always have the following line at the end ...

Oct 04 11:55:01 hurricane virusscan.sh[29915]: ... message not sent
  • 1
    systemd is a pig (sorry). Wouldn't it be easier to set it up as a cron job?
    – gogoud
    Commented Oct 4, 2016 at 21:11
  • @gogoud Yes ... I am beginning to realize that. I was just trying to follow the tutorials on the recommended way to do it for Arch systems. I can make this work with a hand tied behind my back using cron ... Commented Oct 5, 2016 at 1:52

3 Answers 3


According to Arch Wiki mailx forks and systemd kills the main process when script exits. Looks like adding -v to mailx call prevents it from forking, but more correct way to make it work with systemd is to add -Ssendwait to mailx's arguments.


Systemd supports option KillMode, which defaults to control-group. If set to


it won't kill the forked process when script is finished.


There are some benefits to using systemd timers vs cron in terms of handling the logging for you and nice status reports.

systemd does have a more restrictive $PATH environment setting by default compared to cron.

In your examples, you have specified only complete paths, so it's not immediately clear that this is the problem. However, mailx is likely calling some other binaries it expects to find in the $PATH.

It looks like mailx supports a --debug-level option which you could set to trace7 to get maximal debug output.

  • I will try with debug turned on and report back here later. Commented Oct 5, 2016 at 17:40
  • After much trial and error what finally worked for me was adding high verbosity to the mailx part of the command, like so: /usr/bin/clamscan -r -i /path/to/folder | /usr/bin/mailx -vv -A gmail -s "Clam Scan Results $(/usr/bin/date +%F)" [email protected] Commented Oct 30, 2016 at 19:40
  • And once you turned on high verbosity, what the root case that was illuminated? Commented Oct 31, 2016 at 0:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .