A lightweight task scheduling daemon for Linux systems, written in modern C++26. Pika allows you to schedule and manage recurring tasks with cron-like flexibility through a simple CLI interface or as a background daemon.
- Daemon Mode: Run as a background service to execute scheduled tasks automatically
- Client Mode: Interactive CLI to manage tasks in real-time
- Flexible Scheduling: Schedule tasks using
every(recurring) orat(specific time) patterns - Socket-based IPC: Efficient communication between client and daemon via Unix domain sockets
- YAML Configuration: Human-readable task configuration
- Task Management: Add, remove, enable, disable, and list tasks
- Logging: Comprehensive logging system for monitoring task execution
- Systemd Integration: Can be started/stopped via systemd or command-line arguments
The project consists of several key components:
- Daemon: Background process that monitors and executes scheduled tasks
- Scheduler: Manages task scheduling logic and determines when tasks should run
- Client: CLI interface for interacting with the daemon
- Socket: IPC layer for client-daemon communication
- Config: YAML-based configuration parser and task definitions
- Logger: Logging system for tracking daemon and task activities
- C++26 compatible compiler (Clang recommended)
- CMake 4.0 or higher
- Linux operating system (Arch Linux recommended)
- Dependencies (automatically fetched):
- yaml-cpp - YAML parsing library
# Clone the repository
git clone <repository-url>
cd pika
# Create build directory
mkdir -p build
cd build
# Configure and build
cmake ..
make
# The executable will be created as 'pika' in the build directoryStart, stop, or check the daemon status directly:
# Start the daemon
./pika start
# Stop the daemon
./pika stop
# Check daemon status
./pika statusRun without arguments to enter interactive mode:
./pikaSwitch to daemon mode and manage the daemon process:
> daemon # Switch to daemon mode
> start # Start the daemon
> stop # Stop the daemon
> status # Check daemon status
> client # Switch back to client modeManage tasks while the daemon is running:
> add # Add a new task (interactive prompt)
> remove <task_id> # Remove a task by ID
> enable <task_id> # Enable a task by ID
> disable <task_id> # Disable a task by ID
> list # List all tasks
> reload # Reload configuration
> help # Show available commands
> exit # Exit the CLITasks are stored in a YAML configuration file (typically at ~/.config/pika/config.yaml). The configuration format supports two scheduling types:
Execute tasks at regular intervals:
tasks:
- id: "backup"
name: "Daily Backup"
command: "/usr/local/bin/backup.sh"
enabled: true
every:
# only 1 of them or all can be used
minute: 0 # 0-59
hour: 2 # 0-23
day: 0 # 1-31
month: 0 # 1-12Execute tasks at a specific time:
tasks:
- id: "report"
name: "Monthly Report"
command: "/usr/local/bin/generate_report.sh"
enabled: true
at:
minute: 0
hour: 9
day: 1
month: 0- id: Unique identifier for the task
- name: Descriptive name for the task
- command: Shell command to execute
- enabled: Whether the task is active (true/false)
- every or at: Scheduling specification
-
Start the daemon:
./pika start
-
Add a task (using interactive mode):
./pika > add Enter task details in the input asked. Task ID: daily-cleanup Task Name: Daily Cleanup Command to execute: /home/user/scripts/cleanup.sh Schedule: Type (every/at): every Minute (0-59 or 0): 0 Hour (0-23 or 0): 3 Day of Month (1-31 or 0): 0 Month (1-12 or 0): 0
-
List all tasks:
> list -
Disable a task temporarily:
> disable daily-cleanup -
Re-enable when needed:
> enable daily-cleanup
- PID File:
/tmp/pika_daemon.pid(or~/.config/pika/pika.pid) - Log File:
~/.local/share/pika/pika_daemon.log - Config File:
~/.config/pika/pika_config.yaml - Socket:
/tmp/pika_daemon.sock
pika/
├── CMakeLists.txt # Build configuration
├── README.md # This file
├── include/ # Header files
│ ├── client.h # Client interface
│ ├── config.h # Configuration parser
│ ├── daemon.h # Daemon process manager
│ ├── logger.h # Logging system
│ ├── scheduler.h # Task scheduler
│ ├── socket.h # IPC socket handler
│ └── utils.h # Utility functions
└── src/ # Implementation files
├── client.cpp
├── config.cpp
├── daemon.cpp
├── logger.cpp
├── main.cpp
├── scheduler.cpp
├── socket.cpp
└── utils.cpp
Daemon: Manages daemon lifecycle, daemonization, PID file, and signal handlingScheduler: Loads, manages, and executes tasks based on scheduleClient: Provides user interface for task managementSocket: Handles Unix domain socket communicationTask: Represents a scheduled task with timing informationLogger: Thread-safe logging to file
To run Pika as a systemd service, create a service file:
[Unit]
Description=Pika Task Scheduler Daemon
After=network.target
[Service]
Type=forking
ExecStart=/path/to/pika start
ExecStop=/path/to/pika stop
PIDFile=/tmp/pika_daemon.pid
Restart=on-failure
[Install]
WantedBy=multi-user.targetContributions are welcome! Please feel free to submit issues or pull requests.
[Add your license information here]
- Built with yaml-cpp for YAML parsing
- Inspired by cron and systemd timer units