When trying to launch a screen
session via crontab's @reboot
directive, many users encounter issues because cron jobs don't have a proper terminal environment. The standard approach like:
@reboot /usr/bin/screen -dmS gameserver ~/cube/server.sh
often fails because cron lacks the necessary TTY. Here's a more robust solution.
Create a shell script wrapper that properly initializes the environment:
#!/bin/bash # /usr/local/bin/start_gameserver.sh # Set necessary environment variables export USER=$(whoami) export HOME=/home/$USER # Launch screen with detached mode and execute server script /usr/bin/screen -dmS gameserver bash -c "cd ~/cube && ./server.sh"
Make it executable:
chmod +x /usr/local/bin/start_gameserver.sh
Add this to your crontab (crontab -e
):
@reboot /usr/local/bin/start_gameserver.sh > /var/log/gameserver_start.log 2>&1
For modern Linux systems, consider using systemd for better process management:
# /etc/systemd/system/gameserver.service [Unit] Description=Game Server in Screen Session After=network.target [Service] Type=forking User=yourusername ExecStart=/usr/bin/screen -dmS gameserver /home/yourusername/cube/server.sh Restart=always [Install] WantedBy=multi-user.target
Then enable with:
sudo systemctl enable gameserver.service sudo systemctl start gameserver.service
After reboot, check if your screen session is running:
screen -ls
And verify your game server process:
ps aux | grep server.sh
- Ensure
screen
is installed (sudo apt-get install screen
) - Check permissions on all scripts
- Verify PATH variables in cron environment if commands aren't found
- Examine log files for errors
When trying to automate server processes that require an interactive terminal session, you'll quickly discover that cron jobs and screen don't play nicely together by default. The standard approach of just adding a screen command to crontab fails because:
- Cron runs in a non-interactive shell environment
- Screen needs a proper terminal to attach to
- Environment variables and paths may differ
The most reliable method is to create a wrapper script that handles the screen session creation. Here's how to implement it:
#!/bin/bash
# ~/start_server_wrapper.sh
/usr/bin/screen -dmS game_server ~/cube/server.sh
Then make it executable:
chmod +x ~/start_server_wrapper.sh
For your specific case of running at system reboot, the crontab entry should be:
@reboot /home/your_username/start_server_wrapper.sh
After rebooting, check if your screen session is running:
screen -ls
You should see output similar to:
There is a screen on:
12345.game_server (Detached)
1 Socket in /run/screen/S-yourusername.
For more complex scenarios, you might want to:
#!/bin/bash
# Enhanced wrapper script
SCREEN_NAME="game_server"
SERVER_SCRIPT="~/cube/server.sh"
LOG_FILE="~/cube/server.log"
if ! screen -list | grep -q "$SCREEN_NAME"; then
/usr/bin/screen -L -Logfile "$LOG_FILE" -dmS "$SCREEN_NAME" "$SERVER_SCRIPT"
echo "$(date): Started $SCREEN_NAME" >> ~/cube/autostart.log
fi
- Always use full paths to executables in cron jobs
- Check system logs if the script isn't running:
grep CRON /var/log/syslog
- Test your wrapper script manually before adding to crontab
- Consider adding error handling to your wrapper script