When dealing with service management in Linux, the behavior difference between direct execution (sudo nginx
) and init script execution (sudo service nginx start
) often points to environmental or permission issues. Here's what we're observing:
# Successful execution
sudo nginx
# Failing commands
sudo service nginx start
sudo service nginx restart
# Working command
sudo service nginx stop
The strace output reveals a fundamental difference in how the PID file is being handled:
# Working server reads just the PID file path
read(3, "/run/nginx.pid\n", 128) = 15
# Failing server reads additional content
read(3, "/run/nginx.pid\nserver_name\n", 128) = 27
Based on the symptoms, here are the most likely culprits:
- Corrupted or malformed init script (despite appearing identical)
- Environment variables leaking into the service context
- Race conditions during service startup
- PID file handling issues
1. Validate Init Script Integrity
First, verify the actual content being executed:
# Check which script is actually being run
update-rc.d -f nginx defaults
ls -la /etc/init.d/nginx
sha1sum /etc/init.d/nginx
2. Examine Environment Variables
The strace output suggests environment contamination:
# Compare environments
sudo env > /tmp/service_env.txt
sudo -i env > /tmp/interactive_env.txt
diff /tmp/service_env.txt /tmp/interactive_env.txt
3. Debug the Init Script Directly
Add debug statements to the init script temporarily:
# Edit /etc/init.d/nginx
set -x # Add at the beginning of the script
exec 2>&1 | tee /var/log/nginx-init-debug.log
Solution 1: PID File Handling Fix
Modify the init script's PID file handling:
# In /etc/init.d/nginx, replace:
pidfile=${PIDFILE-/run/nginx.pid}
# With:
pidfile=$(cat ${PIDFILE-/run/nginx.pid} | head -n1)
Solution 2: Clean Environment Execution
Force a clean environment when starting:
# Create a wrapper script
sudo sh -c 'env -i /etc/init.d/nginx start'
Solution 3: Systemd Alternative
If available, use systemd directly:
sudo systemctl start nginx
journalctl -u nginx -xe # For detailed logs
- Always validate init scripts after updates
- Implement proper logging in init scripts
- Consider migrating to systemd unit files if possible
- Use configuration management tools to maintain consistency
When managing Ubuntu servers, encountering discrepancies between sudo service nginx start
and direct sudo nginx
execution is more common than you'd expect. Let's dissect this specific case where the service command fails silently while the direct command succeeds.
First, verify all standard configuration points:
# Configuration test
sudo nginx -t
sudo service nginx configtest
# Permission check
ls -la /etc/nginx/nginx.conf
ls -la /var/log/nginx/
# Service script inspection
diff /etc/init.d/nginx working-server:/etc/init.d/nginx
The strace
output reveals a critical difference in PID file handling. The failing system attempts to read both /run/nginx.pid
and some unexpected server_name
data, suggesting:
- Corrupted PID file contents
- Improper service script variable parsing
- Environment variable contamination
Ubuntu's init system expects specific PID file behavior. Try this emergency repair sequence:
# Force-clean any existing PID
sudo rm -f /run/nginx.pid
sudo rm -f /var/run/nginx.pid
# Manual start test
sudo nginx -c /etc/nginx/nginx.conf
# Then attempt service control
sudo service nginx restart
If the issue persists, examine the init script's PID handling. Add debug output temporarily:
# Edit /etc/init.d/nginx
find the start() function and add:
echo "Debug - PIDPATH: $PIDPATH" >&2
echo "Debug - Contents: $(cat $PIDPATH)" >&2
For production systems, consider these reliable alternatives:
# Systemd (Ubuntu 15.04+)
sudo systemctl enable nginx
sudo systemctl start nginx
# Upstart fallback
sudo start nginx
Verify all paths match your distribution's standards:
grep -r '/run/nginx.pid' /etc/nginx/
grep -r 'pid ' /etc/nginx/
grep -r 'user ' /etc/nginx/