I wanted to build something that would force me to work with Linux at a level deeper than simply running commands in a terminal.
That became LinuxGuard.
LinuxGuard is a small cross-language Linux system-intelligence project built using Bash, C, and C#/.NET.
The interesting part isn't just the languages themselves.
It's how they work together.
The idea
The basic workflow is:
LinuxGuard
│
▼
Bash orchestrator
│
┌────────┴────────┐
▼ ▼
Build C Build C#
│
▼
System probe
│
▼
Linux system information
│
▼
system.keyvalue
│
▼
C# report builder
│
▼
system-report.md
The goal was to give every language a specific responsibility instead of making three unrelated programs.
Bash handles orchestration.
C handles low-level system information collection.
C# handles parsing and report generation.
Why three languages?
For a simple system-information tool, using three languages is definitely unnecessary.
That's exactly why I found it interesting.
Each language gives me an opportunity to learn something different.
Bash
Bash is responsible for the workflow.
It handles:
- build commands
- execution order
- dependency checks
- file paths
- status messages
The entire project can be launched with:
./scripts/linuxguard.sh
The script then runs the different stages automatically.
C
C is responsible for the low-level system probe.
The project compiles:
gcc -Wall -Wextra -Wpedantic \
src/c/sysprobe.c \
-o bin/sysprobe
The strict compiler flags are intentional.
They make the compiler report more potential problems instead of simply accepting everything.
The C component collects information from the local Linux system and writes it to a simple key/value file.
C
The C# component takes that collected information and turns it into something more useful for humans.
Instead of leaving the user with raw system data, it generates:
output/system-report.md
So the C# application is essentially the reporting layer.
The important part: the data contract
One of the things I found most interesting wasn't actually one of the languages.
It was the interface between them.
The C program produces:
system.keyvalue
For example:
kernel=...
architecture=...
hostname=...
logical_cpus=...
memory_mb=...
C# then reads that data.
So instead of tightly coupling the two programs together, I created a simple data contract:
C
│
│ writes
▼
system.keyvalue
│
│ reads
▼
C#
This means the C collector and C# report generator can evolve independently as long as they continue to agree on the format.
That's a surprisingly useful software-engineering concept.
One command runs the pipeline
The intended workflow is:
./scripts/linuxguard.sh
The project performs three main stages:
[1/3] Building C probe...
[2/3] Collecting local system snapshot...
[3/3] Building C# report generator...
The result is a Markdown system report along with the raw collected data.
I like this design because the user doesn't have to manually remember which component to build first.
The orchestration layer handles that.
The project structure
The repository is organized roughly like this:
linuxguard/
├── scripts/
│ └── linuxguard.sh
│
├── src/
│ ├── c/
│ │ └── sysprobe.c
│ │
│ └── csharp/
│ ├── LinuxGuard.csproj
│ └── ReportBuilder.cs
│
├── bin/
│ └── sysprobe
│
└── output/
├── system.keyvalue
└── system-report.md
This separation makes it easier to understand which part of the system is responsible for what.
What I learned
Building LinuxGuard taught me that knowing individual programming languages isn't enough.
The interesting part is getting different components to cooperate.
I had to think about:
- process execution
- compilation
- shell scripting
- file I/O
- data formats
- cross-language interfaces
- error handling
- generated files
- build workflows
- Linux system interfaces
The project therefore became as much about software architecture as it was about programming.
It's also deliberately not a security scanner
Despite the name LinuxGuard, the current version is primarily a local system-information and learning tool.
It doesn't attempt to exploit systems or perform offensive security operations.
That distinction is important.
The project currently focuses on building the foundation for a system-intelligence tool.
Future security-oriented possibilities include things like:
- SSH configuration checks
- firewall status
- suspicious permissions
- world-writable files
- outdated packages
- privileged processes
These are planned extensions rather than features I am claiming the current version already provides.
What's next?
There are quite a few directions I could take LinuxGuard.
Some ideas include:
CPU information
GPU information
Disk usage
Mounted filesystems
Running processes
Network interfaces
Listening ports
Firewall status
Security checks
The reporting layer could also eventually support:
Markdown
JSON
HTML
Terminal dashboard
System-health score
Security score
There are also engineering improvements I'd like to explore, such as unit tests, integration tests, GitHub Actions and cross-distribution support.
Final thoughts
LinuxGuard started as a relatively small project.
But it ended up being a useful way to explore how different technologies can fit together.
Bash
↓
Orchestration
C
↓
Low-level system information
C#
↓
Parsing + reporting
The biggest lesson for me was that software architecture isn't about putting everything into one language or one application.
Sometimes the interesting engineering problem is deciding where each responsibility belongs.
That's what I wanted to experiment with in LinuxGuard.
Top comments (0)