How to Properly Redirect stdout/stderr in start-stop-daemon on Linux Systems


5 views

When working with start-stop-daemon on Debian/Ubuntu systems, many developers encounter issues when trying to redirect stdout and stderr to separate log files. The common approach of simply appending shell redirection operators often fails silently, leaving developers puzzled.

The shell redirection needs to happen in the context of the process being executed. When you use:

start-stop-daemon --exec $DAEMON -- $DAEMON_ARGS 1>>$LOG 2>>$ERRLOG

The redirection operators are passed as arguments to the daemon rather than being interpreted by the shell.

Here are two reliable methods to achieve proper output redirection:

Method 1: Using a Shell Wrapper

start-stop-daemon --start --background --make-pidfile --pidfile "$PIDFILE" \
  --chdir "$DAEMON_DIR" --exec /bin/sh -- -c \
  "exec $DAEMON $DAEMON_ARGS 1>>$APPLOG_FILE 2>>$ERRLOG_FILE"

Method 2: Using a Separate Wrapper Script

Create a wrapper script (e.g., /usr/local/bin/my-daemon-wrapper):

#!/bin/sh
exec $DAEMON $DAEMON_ARGS 1>>$APPLOG_FILE 2>>$ERRLOG_FILE

Then call it with:

start-stop-daemon --start --background --make-pidfile --pidfile "$PIDFILE" \
  --chdir "$DAEMON_DIR" --exec /usr/local/bin/my-daemon-wrapper

For production systems, consider these additional improvements:

  • Add log rotation configuration
  • Implement proper file permissions for log files
  • Include timestamping in your log entries

If redirection still doesn't work:

  1. Verify the parent directory of log files exists and is writable
  2. Check file permissions (daemon user must have write access)
  3. Test the redirection outside of start-stop-daemon first
  4. Inspect system logs (/var/log/syslog) for errors

When trying to redirect output streams for daemons managed by start-stop-daemon, many developers encounter unexpected behavior. The fundamental issue lies in how shell redirection interacts with the process hierarchy.

The original script attempts to use shell redirection through an intermediate shell process:


NCMD="exec $DAEMON $DAEMON_ARGS 1>>$APPLOG_FILE 2>>$ERRLOG_FILE"
start-stop-daemon -Sbmv --pidfile $PIDFILE --chdir ${DAEMON_DIR} \
  --exec $DAEMON --startas /bin/sh -- $NCMD

This fails because:

  • The shell interpreting the redirection is not properly preserved
  • start-stop-daemon's process handling interferes with the redirection
  • The PID file ends up tracking the shell process rather than your daemon

Method 1: Using --background with Explicit Redirection

The most reliable approach is to let the daemon itself handle redirection:


start-stop-daemon -Sbmv --pidfile $PIDFILE --chdir ${DAEMON_DIR} \
  --exec $DAEMON -- ${DAEMON_ARGS} >>${APPLOG_FILE} 2>>${ERRLOG_FILE}

Method 2: Using a Wrapper Script

Create a separate wrapper script (/usr/local/bin/my-daemon-wrapper):


#!/bin/sh
exec $DAEMON $DAEMON_ARGS >>${APPLOG_FILE} 2>>${ERRLOG_FILE}

Then call it from your init script:


start-stop-daemon -Sbmv --pidfile $PIDFILE --chdir ${DAEMON_DIR} \
  --exec /usr/local/bin/my-daemon-wrapper
  • Ensure log directories exist and are writable
  • Consider log rotation using logrotate
  • For systemd-based systems, use native logging facilities instead
  • Verify process ownership matches your security requirements

If redirection still fails:

  1. Check file permissions with ls -l /var/log/seed/
  2. Test the redirection manually without start-stop-daemon
  3. Verify shell behavior with strace -f
  4. Check for SELinux/AppArmor restrictions