Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I'm having trouble redirecting C printf statements to a file with a program running as root.

I have a program with several informational printf statements and other libraries which print errors via stderr. I'd like to log these to a file. If I start the program from the command line, I can see stderr and stdout messages.

sudo ./myprogram

If I try to redirect like so,

sudo ./myprogram >> log_file 2>&1

The log_file only contains stderr, and stdout disappears.

I suspect the issue is related to the root user not being connected to stdout, but I haven't found a solution.

My ultimate goal is to run this program at system start as root, while logging stderr and stdout to a log_file.
I've been trying this using crontab,

 sudo crontab -e

and adding the line,

@reboot bin/myprogram >> log_file 2>&1

This generates stderr messages but stdout disappears, same as command line.

Any help is appreciated, thanks!

Edits & updates: Testing this morning, the redirection behaves the same without sudo. A typical printf statement looks like:

printf("info: passed safety check\n");

I'm using a default set up for ubuntu 14.04 on an ARM processor, so I believe I'm using bash. I confirmed with,

echo $SHELL

produces

/bin/bash
share|improve this question
1  
Does it work without sudo? Could you share a line of code that contains a printf statement? –  kraxor Jul 29 at 22:12
    
Are you sure you're using bash with sudo and cron? There are shells which do not understand this redirection syntax. And you could have different shells set up in these different contexts. –  Class Stacker Jul 30 at 6:58
    
May be only stderr generate nothing to output by stdout!? –  Pandya Jul 30 at 12:30

2 Answers 2

up vote 1 down vote accepted

The behaviour of printf() seems to depend on the location of stdout.

  1. If stdout is sent to the console, then printf() is line-buffered and is flushed after a newline is printed.
  2. If stdout is redirected to a file, the buffer is not flushed unless fflush() is called.
  3. Moreover, if printf() is used before stdout is redirected to file, subsequent writes (to the file) are line-buffered and are flushed after newline.

Source: Why does stdout need explicit flushing when redirected to file?

I'm not well versed with C programming, but apparently you need to add fflush(stdout); after every printf statement. Try it out from the command line. If it works, it should work with cron.

More questions on this topic:

share|improve this answer
1  
Yep, adding fflush(stdout); after printf statements captures stdout and stderr messages. Tested using sudo ./myprogram &> log_file (it works as non-root as well). Thanks! –  user2977486 Jul 30 at 16:32

The TLDP HowTo has this nice syntax for redirection of both stdout and stderr:

  @reboot /path/to/program &> /path/to/log

The HowTo says that it's sometimes suitable for cron entries.

share|improve this answer
    
Cron doesn't have @redirect, I tried this. @reboot /path/to/program &> /path/to/log and it produced stderr in the log, but no stdout –  user2977486 Jul 30 at 13:34
    
@user2977486 does the reverse redirection help? First stderr to file, then stdin to err? 2>log 1>&2? –  muru Jul 30 at 13:43
    
same result, this produces error messages but no printf messages in the log –  user2977486 Jul 30 at 13:45
    
@user2977486 And just redirection of stdout, leaving stderr untouched? –  muru Jul 30 at 13:46

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.