1

I want to setup a job that prints output to /dev/stdout, but cron is intercepting it, and sends an e-mail instead

crontab -l
*/1 * * * * echo "hiccup" >> /dev/stdout 2>&1

this is the message:

21   │ From xxx@ltus423288.na.yyy.com  Tue May 21 11:13:00 2019
22   │ Return-Path: <xxx@ltus423288.na.yyy.com>
23   │ X-Original-To: xxx
24   │ Delivered-To: xxx@ltus423288.na.yyy.com
25   │ Received: by ltus423288.na.yyy.com (Postfix, from userid 501)
26   │     id EE6752E98EF; Tue, 21 May 2019 11:13:00 +0200 (CEST)
27   │ From: xxx@ltus423288.na.yyy.com (Cron Daemon)
28   │ To: xxx@ltus423288.na.yyy.com
29   │ Subject: Cron <xxx@ltus423288> echo "hiccup" >> /dev/stdout 2>&1
30   │ X-Cron-Env: <SHELL=/bin/sh>
31   │ X-Cron-Env: <PATH=/usr/bin:/bin>
32   │ X-Cron-Env: <LOGNAME=xxx>
33   │ X-Cron-Env: <USER=xxx>
34   │ X-Cron-Env: <HOME=/Users/xxx>
35   │ Message-Id: <20190521091300.EE6752E98EF@ltus423288.na.yyy.com>
36   │ Date: Tue, 21 May 2019 11:13:00 +0200 (CEST)
37   │ Status: O
38   │
39   │ hiccup

I have already configured fluentd that grabs everything from stdout, so I would prefer cron send job logs there. I tried writing to file which is symbolic link to /dev/stdout but it is not working. I am not sure, if I disable sending mails, and order cron to write to /var/log/syslog (and make it symbolic link to /dev/stdout) cron would fail into infinite loop.

  • It looks to me cron is wrting to stdout. maybe stdout is not what you think. cron job will run when you disconnect, what are you expecting as stdout when not connected ? You should read https://unix.stackexchange.com/questions/4126/what-is-the-exact-difference-between-a-terminal-a-shell-a-tty-and-a-con – Archemar May 21 '19 at 14:06

2 Answers2

7

The point of cron is to run commands without a terminal. That means there is no terminal to output stdout to. That's why it is being mailed.

You can discard its output:

*/1 * * * * echo "hiccup" >> /dev/null 2>&1

You can pipe the stdout of your jobs to a program, e.g. logger to send it to the syslog daemon:

*/1 * * * * echo "hiccup" | logger -t mycronjob 2>&1

Or redirect it to a file:

*/1 * * * * echo "hiccup" >> /var/tmp/some_file 2>&1

But there simply is no terminal where cron jobs can send their stdout to...

Hkoof
  • 1,667
  • 1
    Thanks for response. This is rather strange to me, lets take docker container for example, and command "docker logs". https://docs.docker.com/config/containers/logging/

    For some reason, docker can read stdout without interactive session attached. Why then, cron is unable to write to stdout, so "docker logs" can present it?

    – Orest Lenczyk May 22 '19 at 13:22
  • 1
    So mailing stdout and stderr to the owner of the cron thread is a standard default behavior, if I get it right? – Alexis Dufrenoy Feb 10 '23 at 13:13
0

cron works "headless", so /dev/stdout (and anything you echo makes no sense for it). This is why it captures messages and sends mails instead.

However, you can still instruct it to write to any regular file to feed other software. You can do so with output redirection (the > somefile or >> somefile following the launched command), as shown in examples of the accepted answer :

*/1 * * * * echo "hiccup" >> /var/tmp/some_file 2>&1
Httqm
  • 1,136