When working with Linux startup scripts in /etc/init.d
or /etc/rc.d
, error messages often disappear into the void during boot. Unlike regular terminal commands, these scripts run in a special system context where stdout/stderr aren't always captured by default.
For modern systems using systemd:
journalctl -b -u your-service-name.service
journalctl --boot --priority=err
For older systems using SysVinit, try these approaches:
Method 1: Direct Logging to File
Modify your init script to explicitly redirect output:
#!/bin/sh
exec > /var/log/myscript.log 2>&1
# Your actual script commands here
Method 2: Temporary Terminal Output
For immediate debugging, force output to terminal:
#!/bin/sh
exec > /dev/console 2>&1
echo "Debug: Starting my service"
# Your commands
Method 3: Using logger Utility
Send messages directly to syslog:
#!/bin/sh
logger -t myscript "Starting service"
your_command || logger -t myscript -p user.err "Command failed!"
For complex cases, consider these professional approaches:
Debugging rc.local
Modify /etc/rc.local
to capture all output:
#!/bin/sh
exec 2>> /var/log/rc.local.err
exec 1>> /var/log/rc.local.log
# Your commands
exit 0
Using screen for Interactive Debugging
For really stubborn issues, you can try:
#!/bin/sh
/usr/bin/screen -dmS initscript /path/to/your/script.sh
Then attach to the screen session after boot completes.
- Always implement proper logging in your init scripts
- Include status checks and error handling
- Consider moving to systemd if possible for better logging
- Document your logging approach in script headers
When your carefully crafted init scripts fail during system boot, the frustration begins when you realize the error messages have vanished into the ether. Unlike interactive shell sessions where stderr is immediately visible, boot-time script execution operates differently.
Before implementing custom solutions, exhaust these standard logging locations:
# System messages (traditional location)
/var/log/messages
# Modern systemd systems
journalctl -b
# Specific service logs
/var/log/daemon.log
/var/log/syslog
When standard logs don't capture your script output, implement these proactive measures:
#!/bin/sh
# Redirect all output to a dedicated log file
exec > /var/log/my_script.log 2>&1
# Alternative: Separate stdout and stderr
exec 1>/var/log/my_script_out.log
exec 2>/var/log/my_script_err.log
For complex issues, force the script to run interactively after boot:
# Add this to your init script
if [ "$1" = "debug" ]; then
set -x
shift
fi
Then test with: sudo /etc/init.d/yourscript debug
On modern systems, consider creating a proper systemd service unit:
[Unit]
Description=My Custom Service
[Service]
ExecStart=/path/to/your/script.sh
StandardOutput=journal
StandardError=journal
Restart=on-failure
[Install]
WantedBy=multi-user.target
For production systems, implement log rotation:
# /etc/logrotate.d/my_script
/var/log/my_script.log {
weekly
missingok
rotate 4
compress
notifempty
create 640 root adm
}
Add these functions to your scripts for better debugging:
log() {
echo "$(date '+%Y-%m-%d %T') - $@" >> /var/log/my_script.log
}
die() {
log "FATAL: $@"
exit 1
}