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:
- Verify the parent directory of log files exists and is writable
- Check file permissions (daemon user must have write access)
- Test the redirection outside of start-stop-daemon first
- 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:
- Check file permissions with
ls -l /var/log/seed/
- Test the redirection manually without
start-stop-daemon
- Verify shell behavior with
strace -f
- Check for SELinux/AppArmor restrictions