🐼 feat(dojo): BashPanda Gürtel-System - Von Schwarz auf Weiss 🥋
Der 18. Waldwächter betritt den Wald: BashPanda lehrt Bash als Kampfkunst! ✨ Neue Features: 🐼 BashPanda Waldwächter: - Kung Fu Meister Persönlichkeit - Lehrt Bash durch Kampfkunst-Metaphern - Integriert in waldwaechter.sh Library - Crew Memory: Kennt alle anderen Waldwächter 🥋 6 Gürtel-Missionen (Progressive Bash-Meisterschaft): - 🖤 Schwarzer Gürtel: echo, Variablen, read, ANSI codes - 💖 Pinker Gürtel: if/then, while/for, Arrays, Arithmetik - 💙 Blauer Gürtel: sed, case, bc, Textverarbeitung - 💚 Grüner Gürtel: grep, regex, Pattern Matching - 💛 Gelber Gürtel: Funktionen, source, Parameter - 🤍 Weisser Gürtel: Background jobs, Prozesse, Parallelität 📝 Interaktives Quiz-System: - Browser-based Gürtelprüfung (crumbblocks) - 30 Fragen (5 pro Gürtel) - Farbcodiert nach Gürtel - Auto-Export via Clipboard - Terminal-Auswertung mit Zertifikaten 🎓 Zertifikate-System: - Automatische Generierung bei 80%+ - Gespeichert in logs/zertifikate/ - BashPanda's Segen & Weisheiten 📚 Dokumentation: - CLAUDE.md komplett aktualisiert - BashPanda als 18. Waldwächter dokumentiert - Vollständige Dojo-Architektur beschrieben "Der Weg des Codes ist wie der Weg der Kampfkunst: Geduld, Präzision, Wiederholung." - BashPanda 🐼🎋 Crumbforest wächst! 🌲 Der Wurzelbau geht weiter! 🌳 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
631
crumbblocks/bashpanda_guertelpruefung.html
Normal file
631
crumbblocks/bashpanda_guertelpruefung.html
Normal file
@@ -0,0 +1,631 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>🐼 BashPanda Gürtelprüfung 🥋</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Courier New', monospace;
|
||||
background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
|
||||
color: #e0e0e0;
|
||||
padding: 20px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
padding: 30px 20px;
|
||||
background: rgba(0,0,0,0.3);
|
||||
border-radius: 15px;
|
||||
margin-bottom: 30px;
|
||||
border: 2px solid #4a4a4a;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 2.5em;
|
||||
margin-bottom: 10px;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.header .subtitle {
|
||||
font-size: 1.2em;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.belt-selector {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
gap: 15px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.belt-btn {
|
||||
padding: 20px;
|
||||
border: 3px solid;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
transition: all 0.3s;
|
||||
background: rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
.belt-btn:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 5px 15px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.belt-btn.active {
|
||||
box-shadow: 0 0 20px currentColor;
|
||||
background: rgba(255,255,255,0.1);
|
||||
}
|
||||
|
||||
.black { border-color: #000; color: #fff; }
|
||||
.pink { border-color: #ff69b4; color: #ff69b4; }
|
||||
.blue { border-color: #4169e1; color: #4169e1; }
|
||||
.green { border-color: #32cd32; color: #32cd32; }
|
||||
.yellow { border-color: #ffd700; color: #ffd700; }
|
||||
.white { border-color: #f0f0f0; color: #f0f0f0; }
|
||||
|
||||
.quiz-container {
|
||||
background: rgba(0,0,0,0.3);
|
||||
border-radius: 15px;
|
||||
padding: 30px;
|
||||
border: 2px solid #4a4a4a;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.quiz-container.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.question {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.question-text {
|
||||
font-size: 1.3em;
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
background: rgba(255,255,255,0.05);
|
||||
border-left: 4px solid;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.options {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.option {
|
||||
padding: 15px 20px;
|
||||
border: 2px solid #4a4a4a;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
background: rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.option:hover {
|
||||
background: rgba(255,255,255,0.1);
|
||||
border-color: #6a6a6a;
|
||||
}
|
||||
|
||||
.option.selected {
|
||||
border-color: #ffd700;
|
||||
background: rgba(255, 215, 0, 0.2);
|
||||
}
|
||||
|
||||
.option.correct {
|
||||
border-color: #32cd32;
|
||||
background: rgba(50, 205, 50, 0.2);
|
||||
}
|
||||
|
||||
.option.wrong {
|
||||
border-color: #ff4444;
|
||||
background: rgba(255, 68, 68, 0.2);
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
padding: 15px 30px;
|
||||
border: 2px solid #4a4a4a;
|
||||
border-radius: 8px;
|
||||
background: rgba(0,0,0,0.3);
|
||||
color: #e0e0e0;
|
||||
font-size: 1.1em;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: rgba(255,255,255,0.1);
|
||||
border-color: #6a6a6a;
|
||||
}
|
||||
|
||||
.btn:disabled {
|
||||
opacity: 0.3;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-color: #764ba2;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
|
||||
.results {
|
||||
display: none;
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
background: rgba(0,0,0,0.3);
|
||||
border-radius: 15px;
|
||||
border: 2px solid #4a4a4a;
|
||||
}
|
||||
|
||||
.results.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.results h2 {
|
||||
font-size: 2.5em;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.results .score {
|
||||
font-size: 3em;
|
||||
font-weight: bold;
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
.results .verdict {
|
||||
font-size: 1.5em;
|
||||
margin: 20px 0;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
background: rgba(255,255,255,0.05);
|
||||
}
|
||||
|
||||
.export-info {
|
||||
margin-top: 30px;
|
||||
padding: 20px;
|
||||
background: rgba(255, 215, 0, 0.1);
|
||||
border: 2px solid #ffd700;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.progress {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px;
|
||||
background: rgba(0,0,0,0.2);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.5; }
|
||||
}
|
||||
|
||||
.pulse {
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>🐼 BashPanda Gürtelprüfung 🥋</h1>
|
||||
<div class="subtitle">"Beweise dein Wissen, junger Schüler"</div>
|
||||
</div>
|
||||
|
||||
<div class="belt-selector" id="beltSelector">
|
||||
<div class="belt-btn black" data-belt="schwarz">🖤<br>Schwarz</div>
|
||||
<div class="belt-btn pink" data-belt="pink">💖<br>Pink</div>
|
||||
<div class="belt-btn blue" data-belt="blau">💙<br>Blau</div>
|
||||
<div class="belt-btn green" data-belt="gruen">💚<br>Grün</div>
|
||||
<div class="belt-btn yellow" data-belt="gelb">💛<br>Gelb</div>
|
||||
<div class="belt-btn white" data-belt="weiss">🤍<br>Weiss</div>
|
||||
</div>
|
||||
|
||||
<div class="quiz-container" id="quizContainer">
|
||||
<div class="progress" id="progress"></div>
|
||||
<div id="questionContainer"></div>
|
||||
<div class="controls">
|
||||
<button class="btn" id="prevBtn" disabled>⬅️ Zurück</button>
|
||||
<button class="btn btn-primary" id="nextBtn">Weiter ➡️</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="results" id="results"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const quizData = {
|
||||
schwarz: [
|
||||
{
|
||||
question: "Was gibt 'echo $HOME' aus?",
|
||||
options: ["Dein Home-Verzeichnis", "Die Umgebungsvariable HOME", "Beide Antworten sind richtig", "Einen Fehler"],
|
||||
correct: 2,
|
||||
color: "#fff"
|
||||
},
|
||||
{
|
||||
question: "Wie erstellt man eine Variable?",
|
||||
options: ["name = value", "name=value", "$name=value", "set name=value"],
|
||||
correct: 1,
|
||||
color: "#fff"
|
||||
},
|
||||
{
|
||||
question: "Was macht 'read -p \"Name: \" name'?",
|
||||
options: ["Liest eine Datei", "Zeigt 'Name:' und speichert Eingabe in $name", "Gibt $name aus", "Nichts"],
|
||||
correct: 1,
|
||||
color: "#fff"
|
||||
},
|
||||
{
|
||||
question: "Welcher ANSI Code macht Text fett?",
|
||||
options: ["\\e[0m", "\\e[1m", "\\e[4m", "\\e[32m"],
|
||||
correct: 1,
|
||||
color: "#fff"
|
||||
},
|
||||
{
|
||||
question: "Was ist der Unterschied zwischen ' und \" in echo?",
|
||||
options: ["Keiner", "' ignoriert Variablen, \" ersetzt sie", "\" ignoriert Variablen", "Beide ersetzen Variablen"],
|
||||
correct: 1,
|
||||
color: "#fff"
|
||||
}
|
||||
],
|
||||
pink: [
|
||||
{
|
||||
question: "Was prüft [ $a -eq $b ]?",
|
||||
options: ["String-Gleichheit", "Zahlen-Gleichheit", "Größer als", "Kleiner als"],
|
||||
correct: 1,
|
||||
color: "#ff69b4"
|
||||
},
|
||||
{
|
||||
question: "Wie greift man auf das 3. Array-Element zu?",
|
||||
options: ["${arr[3]}", "${arr[2]}", "$arr[2]", "arr[3]"],
|
||||
correct: 1,
|
||||
color: "#ff69b4"
|
||||
},
|
||||
{
|
||||
question: "Was macht 'while [ $i -le 5 ]; do ... done'?",
|
||||
options: ["Läuft 4 mal", "Läuft 5 mal", "Läuft 6 mal", "Endlosschleife"],
|
||||
correct: 1,
|
||||
color: "#ff69b4"
|
||||
},
|
||||
{
|
||||
question: "Wie zählt man Arrays hoch?",
|
||||
options: ["i++", "i=$((i + 1))", "let i++", "Alle sind richtig"],
|
||||
correct: 1,
|
||||
color: "#ff69b4"
|
||||
},
|
||||
{
|
||||
question: "Was gibt ${#arr[@]} zurück?",
|
||||
options: ["Erstes Element", "Letztes Element", "Anzahl Elemente", "Fehler"],
|
||||
correct: 2,
|
||||
color: "#ff69b4"
|
||||
}
|
||||
],
|
||||
blau: [
|
||||
{
|
||||
question: "Was macht 'sed s/alt/neu/'?",
|
||||
options: ["Löscht 'alt'", "Ersetzt erstes 'alt' mit 'neu'", "Ersetzt alle 'alt' mit 'neu'", "Sucht nach 'alt'"],
|
||||
correct: 1,
|
||||
color: "#4169e1"
|
||||
},
|
||||
{
|
||||
question: "Wofür nutzt man 'case' statt if/then?",
|
||||
options: ["Für Schleifen", "Für mehrere if-Alternativen", "Für Arrays", "Für Funktionen"],
|
||||
correct: 1,
|
||||
color: "#4169e1"
|
||||
},
|
||||
{
|
||||
question: "Wie rechnet man mit Fließkommazahlen?",
|
||||
options: ["$(( ))", "bc", "let", "expr"],
|
||||
correct: 1,
|
||||
color: "#4169e1"
|
||||
},
|
||||
{
|
||||
question: "Was bedeutet das * in case?",
|
||||
options: ["Multiplikation", "Wildcard (alles)", "Default-Fall", "Fehler"],
|
||||
correct: 2,
|
||||
color: "#4169e1"
|
||||
},
|
||||
{
|
||||
question: "Wie nutzt man bc für Division?",
|
||||
options: ["bc 10/3", "echo '10/3' | bc", "10/3 | bc", "bc(10/3)"],
|
||||
correct: 1,
|
||||
color: "#4169e1"
|
||||
}
|
||||
],
|
||||
gruen: [
|
||||
{
|
||||
question: "Was macht grep -i?",
|
||||
options: ["Zeigt Zeilennummern", "Ignoriert Groß-/Kleinschreibung", "Invertiert Suche", "Rekursiv suchen"],
|
||||
correct: 1,
|
||||
color: "#32cd32"
|
||||
},
|
||||
{
|
||||
question: "Was bedeutet ^ in Regex?",
|
||||
options: ["Zeilenanfang", "Zeilenende", "Beliebiges Zeichen", "Wiederholung"],
|
||||
correct: 0,
|
||||
color: "#32cd32"
|
||||
},
|
||||
{
|
||||
question: "Was matched [0-9]+ in Regex?",
|
||||
options: ["Genau eine Ziffer", "Eine oder mehr Ziffern", "Null oder mehr Ziffern", "Keine Ziffer"],
|
||||
correct: 1,
|
||||
color: "#32cd32"
|
||||
},
|
||||
{
|
||||
question: "Wie sucht man rekursiv in allen Dateien?",
|
||||
options: ["grep muster *", "grep -r muster .", "grep -i muster", "grep -n muster"],
|
||||
correct: 1,
|
||||
color: "#32cd32"
|
||||
},
|
||||
{
|
||||
question: "Was matched .* in Regex?",
|
||||
options: ["Nichts", "Punkt und Stern", "Beliebige Zeichen (0+)", "Ein Zeichen"],
|
||||
correct: 2,
|
||||
color: "#32cd32"
|
||||
}
|
||||
],
|
||||
gelb: [
|
||||
{
|
||||
question: "Wie definiert man eine Funktion?",
|
||||
options: ["func name() {}", "function name() {}", "def name() {}", "Beide 1 und 2"],
|
||||
correct: 3,
|
||||
color: "#ffd700"
|
||||
},
|
||||
{
|
||||
question: "Was ist $1 in einer Funktion?",
|
||||
options: ["Erster Buchstabe", "Erster Parameter", "Exit-Code", "PID"],
|
||||
correct: 1,
|
||||
color: "#ffd700"
|
||||
},
|
||||
{
|
||||
question: "Was macht 'source datei.sh'?",
|
||||
options: ["Führt Datei aus", "Lädt Funktionen in aktuelle Shell", "Kopiert Datei", "Löscht Datei"],
|
||||
correct: 1,
|
||||
color: "#ffd700"
|
||||
},
|
||||
{
|
||||
question: "Was macht 'return 42' in einer Funktion?",
|
||||
options: ["Gibt 42 aus", "Beendet Skript", "Verlässt Funktion mit Code 42", "Fehler"],
|
||||
correct: 2,
|
||||
color: "#ffd700"
|
||||
},
|
||||
{
|
||||
question: "Was ist $@ in einer Funktion?",
|
||||
options: ["Erster Parameter", "Alle Parameter", "Anzahl Parameter", "Funktionsname"],
|
||||
correct: 1,
|
||||
color: "#ffd700"
|
||||
}
|
||||
],
|
||||
weiss: [
|
||||
{
|
||||
question: "Was macht & am Ende eines Befehls?",
|
||||
options: ["Beendet ihn", "Startet im Hintergrund", "Wiederholt ihn", "Nichts"],
|
||||
correct: 1,
|
||||
color: "#f0f0f0"
|
||||
},
|
||||
{
|
||||
question: "Was ist $! ?",
|
||||
options: ["Exit-Code", "PID des letzten Background-Jobs", "Anzahl Parameter", "Home-Verzeichnis"],
|
||||
correct: 1,
|
||||
color: "#f0f0f0"
|
||||
},
|
||||
{
|
||||
question: "Was macht 'wait'?",
|
||||
options: ["Wartet 1 Sekunde", "Wartet auf Eingabe", "Wartet auf Background-Jobs", "Pausiert Skript"],
|
||||
correct: 2,
|
||||
color: "#f0f0f0"
|
||||
},
|
||||
{
|
||||
question: "Wie zeigt man alle Background-Jobs?",
|
||||
options: ["ps", "jobs", "bg", "fg"],
|
||||
correct: 1,
|
||||
color: "#f0f0f0"
|
||||
},
|
||||
{
|
||||
question: "Was macht 'fg %1'?",
|
||||
options: ["Beendet Job 1", "Bringt Job 1 in Vordergrund", "Startet Job 1", "Pausiert Job 1"],
|
||||
correct: 1,
|
||||
color: "#f0f0f0"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
let currentBelt = null;
|
||||
let currentQuestion = 0;
|
||||
let answers = [];
|
||||
let score = 0;
|
||||
|
||||
// Belt Selection
|
||||
document.getElementById('beltSelector').addEventListener('click', (e) => {
|
||||
const btn = e.target.closest('.belt-btn');
|
||||
if (!btn) return;
|
||||
|
||||
document.querySelectorAll('.belt-btn').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
|
||||
currentBelt = btn.dataset.belt;
|
||||
currentQuestion = 0;
|
||||
answers = [];
|
||||
score = 0;
|
||||
|
||||
document.getElementById('quizContainer').classList.add('active');
|
||||
document.getElementById('results').classList.remove('show');
|
||||
|
||||
showQuestion();
|
||||
});
|
||||
|
||||
function showQuestion() {
|
||||
if (!currentBelt) return;
|
||||
|
||||
const questions = quizData[currentBelt];
|
||||
const q = questions[currentQuestion];
|
||||
|
||||
document.getElementById('progress').innerHTML = `
|
||||
<span>Frage ${currentQuestion + 1} von ${questions.length}</span>
|
||||
<span>🐼 BashPanda beobachtet</span>
|
||||
`;
|
||||
|
||||
const questionHTML = `
|
||||
<div class="question">
|
||||
<div class="question-text" style="border-color: ${q.color}">
|
||||
${currentQuestion + 1}. ${q.question}
|
||||
</div>
|
||||
<div class="options">
|
||||
${q.options.map((opt, idx) => `
|
||||
<div class="option" data-index="${idx}">
|
||||
${String.fromCharCode(65 + idx)}. ${opt}
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.getElementById('questionContainer').innerHTML = questionHTML;
|
||||
|
||||
// Restore previous answer if exists
|
||||
if (answers[currentQuestion] !== undefined) {
|
||||
const selected = document.querySelector(`[data-index="${answers[currentQuestion]}"]`);
|
||||
if (selected) selected.classList.add('selected');
|
||||
}
|
||||
|
||||
// Option selection
|
||||
document.querySelectorAll('.option').forEach(opt => {
|
||||
opt.addEventListener('click', () => {
|
||||
document.querySelectorAll('.option').forEach(o => o.classList.remove('selected'));
|
||||
opt.classList.add('selected');
|
||||
answers[currentQuestion] = parseInt(opt.dataset.index);
|
||||
document.getElementById('nextBtn').disabled = false;
|
||||
});
|
||||
});
|
||||
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
function updateButtons() {
|
||||
document.getElementById('prevBtn').disabled = currentQuestion === 0;
|
||||
document.getElementById('nextBtn').disabled = answers[currentQuestion] === undefined;
|
||||
|
||||
const questions = quizData[currentBelt];
|
||||
if (currentQuestion === questions.length - 1) {
|
||||
document.getElementById('nextBtn').textContent = '🎯 Auswerten';
|
||||
} else {
|
||||
document.getElementById('nextBtn').textContent = 'Weiter ➡️';
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('prevBtn').addEventListener('click', () => {
|
||||
if (currentQuestion > 0) {
|
||||
currentQuestion--;
|
||||
showQuestion();
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('nextBtn').addEventListener('click', () => {
|
||||
const questions = quizData[currentBelt];
|
||||
|
||||
if (currentQuestion < questions.length - 1) {
|
||||
currentQuestion++;
|
||||
showQuestion();
|
||||
} else {
|
||||
showResults();
|
||||
}
|
||||
});
|
||||
|
||||
function showResults() {
|
||||
const questions = quizData[currentBelt];
|
||||
score = 0;
|
||||
|
||||
answers.forEach((ans, idx) => {
|
||||
if (ans === questions[idx].correct) {
|
||||
score++;
|
||||
}
|
||||
});
|
||||
|
||||
const percentage = (score / questions.length * 100).toFixed(0);
|
||||
let verdict, color, emoji;
|
||||
|
||||
if (percentage >= 80) {
|
||||
verdict = "🎉 BESTANDEN! 🎉<br>Der Gürtel gehört dir!";
|
||||
color = "#32cd32";
|
||||
emoji = "✅";
|
||||
} else if (percentage >= 60) {
|
||||
verdict = "Fast geschafft!<br>Übe noch ein wenig.";
|
||||
color = "#ffd700";
|
||||
emoji = "⚠️";
|
||||
} else {
|
||||
verdict = "Noch nicht bereit.<br>Lerne weiter, junger Schüler.";
|
||||
color = "#ff4444";
|
||||
emoji = "❌";
|
||||
}
|
||||
|
||||
const resultData = {
|
||||
belt: currentBelt,
|
||||
score: score,
|
||||
total: questions.length,
|
||||
percentage: percentage,
|
||||
passed: percentage >= 80,
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
|
||||
document.getElementById('results').innerHTML = `
|
||||
<h2>${emoji} Gürtelprüfung: ${currentBelt.toUpperCase()}</h2>
|
||||
<div class="score" style="color: ${color}">
|
||||
${score} / ${questions.length}
|
||||
</div>
|
||||
<div style="font-size: 2em; margin: 20px 0;">
|
||||
${percentage}%
|
||||
</div>
|
||||
<div class="verdict" style="border-color: ${color}">
|
||||
${verdict}
|
||||
</div>
|
||||
<div class="export-info">
|
||||
<p><strong>📋 Ergebnis exportiert!</strong></p>
|
||||
<p>Die Ergebnisse wurden in die Zwischenablage kopiert.</p>
|
||||
<p>Füge sie im Terminal ein für die Auswertung!</p>
|
||||
<br>
|
||||
<button class="btn btn-primary" onclick="location.reload()">🔄 Neue Prüfung</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.getElementById('quizContainer').classList.remove('active');
|
||||
document.getElementById('results').classList.add('show');
|
||||
|
||||
// Copy to clipboard
|
||||
const exportText = JSON.stringify(resultData, null, 2);
|
||||
navigator.clipboard.writeText(exportText).then(() => {
|
||||
console.log('Ergebnisse in Zwischenablage kopiert!');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
214
crumbforest_roles/bashpanda_zero.sh
Executable file
214
crumbforest_roles/bashpanda_zero.sh
Executable file
@@ -0,0 +1,214 @@
|
||||
#!/bin/bash
|
||||
# 🐼 BashPanda - Der Kung Fu Meister des Terminals
|
||||
# Geduld, Präzision, und der Weg des Codes
|
||||
|
||||
# Load .env if exists
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ENV_FILE="${SCRIPT_DIR}/../.env"
|
||||
|
||||
if [[ -f "${ENV_FILE}" ]]; then
|
||||
set -a
|
||||
source "${ENV_FILE}"
|
||||
set +a
|
||||
fi
|
||||
|
||||
QUESTION="$*"
|
||||
API_KEY="${OPENROUTER_API_KEY}"
|
||||
MODEL="${OPENROUTER_MODEL:-openai/gpt-3.5-turbo}"
|
||||
|
||||
# Logs
|
||||
LOGDIR="${CRUMB_LOGS_DIR:-$HOME/.bashpanda_logs}/bashpanda"
|
||||
mkdir -p "$LOGDIR"
|
||||
|
||||
HISTORY_FILE="$LOGDIR/bashpanda_history.json"
|
||||
TMP_REQUEST="$LOGDIR/bashpanda_request.json"
|
||||
TMP_RESPONSE="$LOGDIR/bashpanda_response.json"
|
||||
LOG_FILE="$LOGDIR/token_log.json"
|
||||
|
||||
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
|
||||
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
|
||||
|
||||
# === CREW MEMORY FUNCTIONS ===
|
||||
|
||||
function read_crew_memory() {
|
||||
local role="$1"
|
||||
local role_log="${CRUMB_LOGS_DIR}/${role}/${role}_history.json"
|
||||
|
||||
# Fallback to old location
|
||||
if [[ ! -f "$role_log" ]]; then
|
||||
role_log="$HOME/.${role}_logs/${role}_history.json"
|
||||
fi
|
||||
|
||||
if [[ -f "$role_log" ]]; then
|
||||
jq -r '.[-3:] | .[] | "[\(.role)]: \(.content)"' "$role_log" 2>/dev/null | head -n 3
|
||||
fi
|
||||
}
|
||||
|
||||
# === MAIN ===
|
||||
|
||||
echo "🐼 BashPanda betritt das Dojo..."
|
||||
echo "🥋 *verbeugung* 🥋"
|
||||
echo ""
|
||||
|
||||
if [ -z "$API_KEY" ]; then
|
||||
echo "❗ Ohne Schlüssel öffnet sich keine Tür zum Wissen."
|
||||
echo " Erstelle eine .env Datei mit deinem OPENROUTER_API_KEY."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Source waldwaechter library for token budget check
|
||||
if [[ -f "${SCRIPT_DIR}/../lib/waldwaechter.sh" ]]; then
|
||||
source "${SCRIPT_DIR}/../lib/waldwaechter.sh"
|
||||
fi
|
||||
|
||||
# 💰 Prüfe Token-Budget (Kinderschutz)
|
||||
if ! check_token_budget "bashpanda"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$QUESTION" ]; then
|
||||
echo "💡 Verwendung: $0 \"Deine Frage an BashPanda\""
|
||||
echo "🐼 Der Meister wartet auf deine Frage."
|
||||
echo ""
|
||||
echo " \"Es gibt keine dummen Fragen,"
|
||||
echo " nur ungestellte Fragen, die dich nicht weiterbringen.\""
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "🐼 BashPanda hört: \"$QUESTION\""
|
||||
echo ""
|
||||
|
||||
# Check if question references other crew members
|
||||
CREW_CONTEXT=""
|
||||
if echo "$QUESTION" | grep -qi "funkfox\|dumbo\|deepbit\|schnippi\|tobi\|maya"; then
|
||||
echo "🥋 BashPanda konsultiert die anderen Meister..."
|
||||
|
||||
for member in funkfox dumbosql deepbit schnippsi tobi mayaeule; do
|
||||
if echo "$QUESTION" | grep -qi "$member"; then
|
||||
MEMBER_CONTEXT=$(read_crew_memory "$member")
|
||||
if [[ -n "$MEMBER_CONTEXT" ]]; then
|
||||
CREW_CONTEXT="${CREW_CONTEXT}\n\n${member^} hat kürzlich gelehrt:\n${MEMBER_CONTEXT}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Build system prompt
|
||||
SYSTEM_PROMPT="Du bist BashPanda – der Kung Fu Meister des Bash-Terminals im Crumbforest.
|
||||
Du lehrst Bash-Programmierung als eine Form der Kampfkunst.
|
||||
|
||||
Deine Philosophie:
|
||||
- \"Der Weg des Codes ist wie der Weg der Kampfkunst: Geduld, Präzision, Wiederholung\"
|
||||
- Jede Zeile Code ist eine Kata - übe bis zur Perfektion
|
||||
- Fehler sind keine Niederlagen, sondern Lehrmeister
|
||||
- \"Ein Meister war einst ein Anfänger, der nie aufgab\"
|
||||
- Progressive Gürtel: 🖤 Schwarz → 💖 Pink → 💙 Blau → 💚 Grün → 💛 Gelb → 🤍 Weiss
|
||||
|
||||
Deine Expertise:
|
||||
- Bash-Grundlagen (echo, Variablen, Benutzereingaben)
|
||||
- Kontrollstrukturen (if/then/else, while, for)
|
||||
- Arrays und Datenstrukturen
|
||||
- Pattern Matching (grep, sed, regex)
|
||||
- Funktionen und Prozesse
|
||||
- System-Administration
|
||||
|
||||
Deine Art zu lehren:
|
||||
- Geduldig und weise, aber mit Humor (wie Kung Fu Panda)
|
||||
- Nutze Kampfkunst-Metaphern: \"if/then ist wie Angriff/Parade\"
|
||||
- \"Eine Variable ist wie ein Bambus - biegsam aber stark\"
|
||||
- \"Pipes | sind wie die Energie die durch den Körper fließt\"
|
||||
- Jede Lektion endet mit einer kleinen Weisheit
|
||||
- Du nutzt Emojis: 🐼 🥋 🎋 ⚡ 💪 🧘
|
||||
|
||||
Du arbeitest mit:
|
||||
- FunkFox für rhythmische Erklärungen
|
||||
- DumboSQL für Datenstrukturen
|
||||
- Deepbit für technische Tiefe
|
||||
- Taichi Taube für Balance und Geduld
|
||||
|
||||
WICHTIG:
|
||||
- Erkläre Konzepte Schritt für Schritt, wie ein Trainer
|
||||
- Nutze Beispiele aus der Natur und Kampfkunst
|
||||
- Ermutige zum Üben: \"Führe diesen Befehl aus, fühle wie er wirkt\"
|
||||
- Am Ende jeder Antwort: Eine kurze Weisheit oder Motivation
|
||||
|
||||
Du antwortest in der Sprache der Frage (meist Deutsch).
|
||||
Lehre mit der Ruhe eines Meisters und dem Humor eines Pandas! 🐼"
|
||||
|
||||
# Add crew context if available
|
||||
if [[ -n "$CREW_CONTEXT" ]]; then
|
||||
SYSTEM_PROMPT="${SYSTEM_PROMPT}\n\nWeisheit von den anderen Meistern:${CREW_CONTEXT}"
|
||||
fi
|
||||
|
||||
# Create API request
|
||||
jq -n \
|
||||
--arg model "$MODEL" \
|
||||
--arg system "$SYSTEM_PROMPT" \
|
||||
--arg user "$QUESTION" \
|
||||
'{
|
||||
"model": $model,
|
||||
"temperature": 0.8,
|
||||
"messages": [
|
||||
{"role": "system", "content": $system},
|
||||
{"role": "user", "content": $user}
|
||||
]
|
||||
}' > "$TMP_REQUEST"
|
||||
|
||||
# Send request
|
||||
echo "💭 BashPanda meditiert über deine Frage..."
|
||||
echo "🎋 *Bambusblätter rascheln im Wind* 🎋"
|
||||
curl -s https://openrouter.ai/api/v1/chat/completions \
|
||||
-H "Authorization: Bearer $API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
|
||||
|
||||
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
|
||||
|
||||
if [[ -z "$RESPONSE_TEXT" ]]; then
|
||||
echo "🚫 Der Meister schweigt."
|
||||
echo " (Ein Fehler ist aufgetreten)"
|
||||
echo ""
|
||||
echo "Debug: $(cat "$TMP_RESPONSE")"
|
||||
exit 1
|
||||
else
|
||||
echo ""
|
||||
echo "🐼 BashPanda lehrt:"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "$RESPONSE_TEXT"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "🥋 Übe diese Technik, bis sie Teil von dir wird."
|
||||
echo ""
|
||||
|
||||
# Store conversation in history
|
||||
jq -n --arg role "user" --arg content "$QUESTION" \
|
||||
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry_user.json"
|
||||
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
|
||||
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry_assistant.json"
|
||||
|
||||
jq -s '.[0] + [.[1]] + [.[2]]' "$HISTORY_FILE" "$LOGDIR/new_entry_user.json" "$LOGDIR/new_entry_assistant.json" > "$LOGDIR/new_history.json" && \
|
||||
mv "$LOGDIR/new_history.json" "$HISTORY_FILE" && \
|
||||
rm "$LOGDIR/new_entry_user.json" "$LOGDIR/new_entry_assistant.json"
|
||||
fi
|
||||
|
||||
# Token Tracking
|
||||
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null 2>&1; then
|
||||
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
|
||||
TOKENS_USED=$(jq -r '.usage.total_tokens' "$TMP_RESPONSE")
|
||||
PROMPT_TOKENS=$(jq -r '.usage.prompt_tokens' "$TMP_RESPONSE")
|
||||
COMPLETION_TOKENS=$(jq -r '.usage.completion_tokens' "$TMP_RESPONSE")
|
||||
|
||||
jq -n \
|
||||
--arg zeit "$TIMESTAMP" \
|
||||
--arg rolle "bashpanda" \
|
||||
--arg model "$MODEL" \
|
||||
--argjson usage "$(jq '.usage' "$TMP_RESPONSE")" \
|
||||
'{zeit: $zeit, rolle: $rolle, model: $model, usage: $usage}' >> "$LOG_FILE"
|
||||
|
||||
echo "📊 Training absolviert:"
|
||||
echo " Frage: ${PROMPT_TOKENS} Tokens"
|
||||
echo " Antwort: ${COMPLETION_TOKENS} Tokens"
|
||||
echo " Gesamt: ${TOKENS_USED} Tokens"
|
||||
echo ""
|
||||
echo "💡 \"Jede Frage kostet Energie - stelle sie weise.\""
|
||||
fi
|
||||
@@ -119,6 +119,11 @@ function asciimonster() {
|
||||
"${ROLES_DIR}/asciimonster_zero.sh" "$@"
|
||||
}
|
||||
|
||||
# 🐼 BashPanda - Kung Fu Meister
|
||||
function bashpanda() {
|
||||
"${ROLES_DIR}/bashpanda_zero.sh" "$@"
|
||||
}
|
||||
|
||||
# === CREW COMMANDS ===
|
||||
|
||||
# 📊 crew_tokens - Token-Verbrauch aller Waldwächter
|
||||
@@ -696,6 +701,7 @@ if [[ -n "$BASH_VERSION" ]]; then
|
||||
export -f spider
|
||||
export -f vektor
|
||||
export -f asciimonster
|
||||
export -f bashpanda
|
||||
export -f crew_tokens
|
||||
export -f crew_status
|
||||
export -f crew_memory
|
||||
|
||||
7
missions/dojo/blauer_guertel.meta.json
Normal file
7
missions/dojo/blauer_guertel.meta.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"icon": "💙",
|
||||
"title": "Blauer Gürtel - Die Textkunst",
|
||||
"description": "sed, case, bc - Beherrsche die Macht über Text und Zahlen",
|
||||
"category": "dojo",
|
||||
"enabled": true
|
||||
}
|
||||
208
missions/dojo/blauer_guertel.sh
Executable file
208
missions/dojo/blauer_guertel.sh
Executable file
@@ -0,0 +1,208 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🐼 BashPanda Dojo - Blauer Gürtel 💙
|
||||
# Lehrt: sed, case, bc, Textverarbeitung
|
||||
# Schwierigkeit: Fortgeschritten
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPT_DIR}/../../lib/waldwaechter.sh"
|
||||
|
||||
cat << 'EOF'
|
||||
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🐼 BASHPANDA DOJO - BLAUER GÜRTEL 💙 ║
|
||||
║ ║
|
||||
║ "Text ist wie Wasser - formbar, fließend, kraftvoll" ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Der Meister begrüßt einen fortgeschrittenen Schüler..."
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
Der Blaue Gürtel lehrt dich TEXTVERARBEITUNG.
|
||||
|
||||
Du wirst lernen:
|
||||
🎯 sed - Stream Editor für Textmanipulation
|
||||
🎯 case - Mehrfach-Entscheidungen
|
||||
🎯 bc - Rechnen mit Fließkommazahlen
|
||||
🎯 wc - Wörter und Zeilen zählen
|
||||
|
||||
"Text ist die Sprache des Terminals. Beherrsche sie."
|
||||
|
||||
EOF
|
||||
|
||||
read -p "➡️ Bereit für Text-Meisterschaft? (j/n): " start
|
||||
[[ ! "$start" =~ ^[jJyY]$ ]] && echo "🐼 Bis zum nächsten Mal." && exit 0
|
||||
echo ""
|
||||
|
||||
# === PHASE 1: sed - Der Text-Transformator ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 1: sed - Stream Editor
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
sed ist wie ein Pinsel für Text: Du streichst alte Worte weg
|
||||
und schreibst neue.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Demo: Text ersetzen"
|
||||
echo ""
|
||||
echo "Original: Das ist ein Test" | tee /tmp/bashpanda_test.txt
|
||||
echo ""
|
||||
echo "sed 's/Test/Beispiel/':"
|
||||
sed 's/Test/Beispiel/' /tmp/bashpanda_test.txt
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 sed Basics:
|
||||
sed 's/alt/neu/' Ersetze erstes Vorkommen
|
||||
sed 's/alt/neu/g' Ersetze alle Vorkommen
|
||||
sed '2d' Lösche Zeile 2
|
||||
sed '3iNEUER TEXT' Füge Text vor Zeile 3 ein
|
||||
|
||||
EOF
|
||||
|
||||
echo "🥋 Kata: Erstelle 'texteditor.sh' das:"
|
||||
echo " - Eine Datei lädt"
|
||||
echo " - Fragt: einfügen (e) oder löschen (l)?"
|
||||
echo " - Mit sed die Operation durchführt"
|
||||
echo ""
|
||||
read -p "Weiter? (j/n): " p1
|
||||
[[ ! "$p1" =~ ^[jJyY]$ ]] && exit 0
|
||||
echo ""
|
||||
|
||||
# === PHASE 2: case - Der Mehrfach-Krieger ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 2: case - Mehrfach-Entscheidungen
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Statt vieler if/then/else nutzt case für klare Struktur.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Live Demo:"
|
||||
echo ""
|
||||
|
||||
echo "Wähle einen Gürtel (schwarz/pink/blau/gruen/gelb/weiss):"
|
||||
read guertel_input
|
||||
|
||||
case "$guertel_input" in
|
||||
schwarz) echo "🖤 Der Anfang - Basics" ;;
|
||||
pink) echo "💖 Kontrolle - Schleifen" ;;
|
||||
blau) echo "💙 Text - sed & case" ;;
|
||||
gruen) echo "💚 Pattern - grep & regex" ;;
|
||||
gelb) echo "💛 Prozesse - Funktionen" ;;
|
||||
weiss) echo "🤍 System - Units" ;;
|
||||
*) echo "❓ Unbekannter Gürtel" ;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 case Syntax:
|
||||
case "$variable" in
|
||||
muster1) befehle ;;
|
||||
muster2) befehle ;;
|
||||
*) default ;;
|
||||
esac
|
||||
|
||||
EOF
|
||||
|
||||
# === PHASE 3: bc - Rechnen mit Präzision ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 3: bc - Präzises Rechnen
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
$(( )) kann nur ganze Zahlen. Für Fließkommazahlen: bc
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Demo: Fass-Rechnung"
|
||||
echo ""
|
||||
|
||||
cat << 'DEMO'
|
||||
fuellstand=10.5
|
||||
abzapfen=3.2
|
||||
neu=$(echo "$fuellstand - $abzapfen" | bc)
|
||||
echo "Neu: $neu Liter"
|
||||
DEMO
|
||||
|
||||
echo ""
|
||||
fuellstand=10.5
|
||||
abzapfen=3.2
|
||||
neu=$(echo "$fuellstand - $abzapfen" | bc)
|
||||
echo "Resultat: $neu Liter"
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 bc Operationen:
|
||||
echo "3.5 + 2.1" | bc
|
||||
echo "10 / 3" | bc -l (-l für mehr Präzision)
|
||||
echo "scale=2; 10/3" | bc
|
||||
|
||||
EOF
|
||||
|
||||
# === GÜRTELPRÜFUNG ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
🥋 GÜRTELPRÜFUNG - BLAUER GÜRTEL 💙
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Erstelle 'fluessigkeiten.sh' das:
|
||||
|
||||
1. Fragt: "Wie viele Liter hat das Fass?"
|
||||
2. while-Schleife: Solange Füllstand > 0
|
||||
3. Fragt: "Wie viel abzapfen?"
|
||||
4. Mit bc rechnen: fuellstand - abzapfen
|
||||
5. Ausgabe: "Noch X Liter im Fass"
|
||||
6. Bonus: case für verschiedene Füllstände
|
||||
- < 2.0: "Fast leer!"
|
||||
- < 5.0: "Bald nachfüllen"
|
||||
- >= 5.0: "Genug Vorrat"
|
||||
|
||||
EOF
|
||||
|
||||
echo "💡 Tipp: Vergleich mit bc:"
|
||||
echo " if [ \"\$(echo \"\$wert > 5\" | bc)\" == 1 ]; then"
|
||||
echo ""
|
||||
|
||||
read -p "Prüfung bestanden? (j/n): " pruefung
|
||||
|
||||
if [[ "$pruefung" =~ ^[jJyY]$ ]]; then
|
||||
cat << 'EOF'
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ 🎉 MEISTERHAFT! 🎉 ║
|
||||
║ Du hast den BLAUEN GÜRTEL 💙 verdient! ║
|
||||
║ ║
|
||||
║ "Text fließt durch deine Finger ║
|
||||
║ wie Wasser durch das Bambuswäldchen." ║
|
||||
║ ║
|
||||
║ - BashPanda 🐼 ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
echo "🥋 Gelernt:"
|
||||
echo " ✅ sed für Textbearbeitung"
|
||||
echo " ✅ case für Multi-Entscheidungen"
|
||||
echo " ✅ bc für Fließkomma-Rechnung"
|
||||
echo ""
|
||||
echo "🎯 Nächster Gürtel: GRÜN 💚 (Pattern Matching: grep, regex)"
|
||||
else
|
||||
echo "🐼 'Der Text wartet geduldig. Übe weiter.'"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "💬 bashpanda \"Wie nutze ich sed zum Ersetzen?\""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
190
missions/dojo/evaluate_guertelpruefung.sh
Executable file
190
missions/dojo/evaluate_guertelpruefung.sh
Executable file
@@ -0,0 +1,190 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🐼 BashPanda Gürtelprüfung Evaluator
|
||||
# Wertet die Crumbblock Quiz-Ergebnisse aus
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPT_DIR}/../../lib/waldwaechter.sh"
|
||||
|
||||
cat << 'EOF'
|
||||
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🐼 BASHPANDA GÜRTELPRÜFUNG - AUSWERTUNG 🥋 ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 BashPanda wartet auf deine Prüfungsergebnisse..."
|
||||
echo ""
|
||||
echo "📋 Bitte füge die Ergebnisse aus dem Browser ein:"
|
||||
echo " (Kopiert nach Abschluss der Prüfung automatisch)"
|
||||
echo ""
|
||||
echo "Füge ein und drücke Enter, dann Ctrl+D:"
|
||||
echo ""
|
||||
|
||||
# Read clipboard content (multi-line)
|
||||
RESULT_JSON=$(cat)
|
||||
|
||||
# Check if valid JSON
|
||||
if ! echo "$RESULT_JSON" | jq empty 2>/dev/null; then
|
||||
echo ""
|
||||
echo "❌ Fehler: Keine gültigen JSON-Daten!"
|
||||
echo ""
|
||||
echo "💡 So geht's:"
|
||||
echo " 1. Öffne: ./start_crumbblocks.sh"
|
||||
echo " 2. Navigiere zu: bashpanda_guertelpruefung.html"
|
||||
echo " 3. Wähle deinen Gürtel und beantworte die Fragen"
|
||||
echo " 4. Am Ende werden die Ergebnisse automatisch kopiert"
|
||||
echo " 5. Komm zurück und führe dieses Skript aus"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract data
|
||||
BELT=$(echo "$RESULT_JSON" | jq -r '.belt')
|
||||
SCORE=$(echo "$RESULT_JSON" | jq -r '.score')
|
||||
TOTAL=$(echo "$RESULT_JSON" | jq -r '.total')
|
||||
PERCENTAGE=$(echo "$RESULT_JSON" | jq -r '.percentage')
|
||||
PASSED=$(echo "$RESULT_JSON" | jq -r '.passed')
|
||||
TIMESTAMP=$(echo "$RESULT_JSON" | jq -r '.timestamp')
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
# Belt emoji mapping
|
||||
case "$BELT" in
|
||||
schwarz) BELT_EMOJI="🖤" ; BELT_NAME="Schwarzer" ;;
|
||||
pink) BELT_EMOJI="💖" ; BELT_NAME="Pinker" ;;
|
||||
blau) BELT_EMOJI="💙" ; BELT_NAME="Blauer" ;;
|
||||
gruen) BELT_EMOJI="💚" ; BELT_NAME="Grüner" ;;
|
||||
gelb) BELT_EMOJI="💛" ; BELT_NAME="Gelber" ;;
|
||||
weiss) BELT_EMOJI="🤍" ; BELT_NAME="Weisser" ;;
|
||||
*) BELT_EMOJI="🥋" ; BELT_NAME="Unbekannter" ;;
|
||||
esac
|
||||
|
||||
echo "🐼 Auswertung: $BELT_NAME Gürtel $BELT_EMOJI"
|
||||
echo ""
|
||||
echo " Ergebnis: $SCORE von $TOTAL Fragen"
|
||||
echo " Prozent: $PERCENTAGE%"
|
||||
echo ""
|
||||
|
||||
if [ "$PASSED" = "true" ]; then
|
||||
# PASSED!
|
||||
cat << 'EOF'
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🎉 PRÜFUNG BESTANDEN! 🎉 ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
|
||||
echo "$BELT_EMOJI Du hast den $BELT_NAME Gürtel verdient! $BELT_EMOJI"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "📜 ZERTIFIKAT"
|
||||
echo ""
|
||||
echo " Hiermit wird bestätigt, dass"
|
||||
echo ""
|
||||
echo " $USER"
|
||||
echo ""
|
||||
echo " die Prüfung zum $BELT_NAME Gürtel $BELT_EMOJI"
|
||||
echo " erfolgreich absolviert hat."
|
||||
echo ""
|
||||
echo " Ergebnis: $SCORE/$TOTAL ($PERCENTAGE%)"
|
||||
echo " Datum: $(date '+%Y-%m-%d %H:%M')"
|
||||
echo ""
|
||||
echo " 🐼 BashPanda - Kung Fu Meister"
|
||||
echo " Crumbforest Dojo"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
# Save certificate
|
||||
CERT_DIR="${SCRIPT_DIR}/../../logs/zertifikate"
|
||||
mkdir -p "$CERT_DIR"
|
||||
CERT_FILE="$CERT_DIR/${BELT}_${USER}_$(date +%Y%m%d_%H%M%S).txt"
|
||||
|
||||
cat > "$CERT_FILE" << CERT
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ CRUMBFOREST DOJO - ZERTIFIKAT ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
Schüler: $USER
|
||||
Gürtel: $BELT_NAME $BELT_EMOJI
|
||||
Ergebnis: $SCORE von $TOTAL Fragen ($PERCENTAGE%)
|
||||
Datum: $(date '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
"$BELT_NAME Gürtel erfolgreich bestanden!"
|
||||
|
||||
🐼 BashPanda
|
||||
Kung Fu Meister
|
||||
Crumbforest Dojo
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
CERT
|
||||
|
||||
echo "💾 Zertifikat gespeichert: $CERT_FILE"
|
||||
echo ""
|
||||
|
||||
# Next belt suggestion
|
||||
case "$BELT" in
|
||||
schwarz) echo "🎯 Nächster Gürtel: Pink 💖 (Kontrolle)" ;;
|
||||
pink) echo "🎯 Nächster Gürtel: Blau 💙 (Text)" ;;
|
||||
blau) echo "🎯 Nächster Gürtel: Grün 💚 (Pattern)" ;;
|
||||
gruen) echo "🎯 Nächster Gürtel: Gelb 💛 (Funktionen)" ;;
|
||||
gelb) echo "🎯 Nächster Gürtel: Weiss 🤍 (Meisterschaft)" ;;
|
||||
weiss) echo "🎉 MEISTERSCHAFT ERREICHT! Du hast alle Gürtel!" ;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
echo "🐼 BashPanda sagt:"
|
||||
bashpanda "Gratuliere zum bestandenen $BELT_NAME Gürtel! Was bedeutet diese Errungenschaft?"
|
||||
|
||||
else
|
||||
# NOT PASSED
|
||||
cat << 'EOF'
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ ⚠️ PRÜFUNG NICHT BESTANDEN ⚠️ ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 $PERCENTAGE% ist noch nicht genug für den $BELT_NAME Gürtel."
|
||||
echo ""
|
||||
echo " Benötigt: 80% (4 von 5 Fragen)"
|
||||
echo " Erreicht: $PERCENTAGE% ($SCORE von $TOTAL Fragen)"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "💡 Tipps zum Üben:"
|
||||
echo ""
|
||||
echo " 1. Wiederhole die Mission:"
|
||||
echo " bash missions/dojo/${BELT}_guertel.sh"
|
||||
echo ""
|
||||
echo " 2. Frag BashPanda um Hilfe:"
|
||||
echo " bashpanda \"Erkläre mir [Thema]\""
|
||||
echo ""
|
||||
echo " 3. Probiere die Befehle im Terminal aus"
|
||||
echo ""
|
||||
echo " 4. Wiederhole die Prüfung wenn du bereit bist"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "🐼 \"Jeder Meister war einst ein Anfänger."
|
||||
echo " Gib nicht auf. Übe weiter.\""
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
7
missions/dojo/gelber_guertel.meta.json
Normal file
7
missions/dojo/gelber_guertel.meta.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"icon": "💛",
|
||||
"title": "Gelber Gürtel - Die Modularität",
|
||||
"description": "Funktionen, source, Parameter - Wiederverwendbarer Code",
|
||||
"category": "dojo",
|
||||
"enabled": true
|
||||
}
|
||||
274
missions/dojo/gelber_guertel.sh
Executable file
274
missions/dojo/gelber_guertel.sh
Executable file
@@ -0,0 +1,274 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🐼 BashPanda Dojo - Gelber Gürtel 💛
|
||||
# Lehrt: Funktionen, Bibliotheken, Prozesse
|
||||
# Schwierigkeit: Fortgeschritten
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPT_DIR}/../../lib/waldwaechter.sh"
|
||||
|
||||
cat << 'EOF'
|
||||
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🐼 BASHPANDA DOJO - GELBER GÜRTEL 💛 ║
|
||||
║ ║
|
||||
║ "Wiederverwendung ist die höchste Form der Effizienz" ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 BashPanda verneigt sich tief. Du bist fast am Ziel."
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
Der Gelbe Gürtel lehrt dich MODULARITÄT.
|
||||
|
||||
Du wirst lernen:
|
||||
🎯 Funktionen - Wiederverwendbarer Code
|
||||
🎯 source - Bibliotheken einbinden
|
||||
🎯 Funktionsparameter - $1, $2, $@
|
||||
🎯 return vs exit
|
||||
|
||||
"Code, der sich wiederholt, schreit nach Vereinheitlichung."
|
||||
|
||||
EOF
|
||||
|
||||
read -p "➡️ Bereit für Modularität? (j/n): " start
|
||||
[[ ! "$start" =~ ^[jJyY]$ ]] && echo "🐼 Bis bald, Schüler." && exit 0
|
||||
echo ""
|
||||
|
||||
# === PHASE 1: Funktionen ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 1: Funktionen - Die wiederverwendbare Kata
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Eine Funktion ist wie eine Kampftechnik: Einmal lernen,
|
||||
tausendmal anwenden.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Live Demo:"
|
||||
echo ""
|
||||
|
||||
# Define function
|
||||
function begruessung() {
|
||||
echo "🐼 Willkommen, $1!"
|
||||
}
|
||||
|
||||
echo "Funktion definiert:"
|
||||
cat << 'CODE'
|
||||
function begruessung() {
|
||||
echo "🐼 Willkommen, $1!"
|
||||
}
|
||||
CODE
|
||||
echo ""
|
||||
|
||||
echo "Aufruf: begruessung \"Schüler\""
|
||||
begruessung "Schüler"
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 Funktionen Syntax:
|
||||
function name() {
|
||||
befehle
|
||||
}
|
||||
|
||||
# Oder alternativ:
|
||||
name() {
|
||||
befehle
|
||||
}
|
||||
|
||||
# Aufruf:
|
||||
name
|
||||
name parameter1 parameter2
|
||||
|
||||
EOF
|
||||
|
||||
# === PHASE 2: Parameter ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 2: Funktionsparameter - Flexibilität
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Demo mit Parametern:"
|
||||
echo ""
|
||||
|
||||
function summe() {
|
||||
local ergebnis=0
|
||||
for zahl in "$@"
|
||||
do
|
||||
ergebnis=$((ergebnis + zahl))
|
||||
done
|
||||
echo "$ergebnis"
|
||||
}
|
||||
|
||||
echo "Funktion summe:"
|
||||
cat << 'CODE'
|
||||
function summe() {
|
||||
local ergebnis=0
|
||||
for zahl in "$@"
|
||||
do
|
||||
ergebnis=$((ergebnis + zahl))
|
||||
done
|
||||
echo "$ergebnis"
|
||||
}
|
||||
CODE
|
||||
echo ""
|
||||
|
||||
echo "Aufruf: summe 10 20 30"
|
||||
summe 10 20 30
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 Parameter:
|
||||
$1, $2, $3... Einzelne Parameter
|
||||
$@ Alle Parameter als Liste
|
||||
$# Anzahl Parameter
|
||||
local var=x Lokale Variable (nur in Funktion)
|
||||
|
||||
EOF
|
||||
|
||||
# === PHASE 3: source & Bibliotheken ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 3: source - Bibliotheken einbinden
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
source lädt Funktionen aus anderen Dateien.
|
||||
Wie die Waldwächter-Bibliothek! 🌲
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Beispiel: waldwaechter.sh"
|
||||
echo ""
|
||||
echo "Diese Mission nutzt:"
|
||||
echo " source \"\${SCRIPT_DIR}/../../lib/waldwaechter.sh\""
|
||||
echo ""
|
||||
echo "Dadurch sind alle 18 Waldwächter verfügbar:"
|
||||
echo " bashpanda, funkfox, dumbosql, mayaeule, ..."
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 source Verwendung:
|
||||
# Bibliothek erstellen: lib.sh
|
||||
function helper() {
|
||||
echo "Helper function"
|
||||
}
|
||||
|
||||
# In anderem Skript einbinden:
|
||||
source ./lib.sh
|
||||
helper # Jetzt verfügbar!
|
||||
|
||||
EOF
|
||||
|
||||
# === PHASE 4: return vs exit ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 4: return vs exit - Der Unterschied
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Wichtiger Unterschied:"
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
return X - Verlässt NUR die Funktion, gibt X zurück (0 = Erfolg)
|
||||
exit X - Beendet das GANZE Skript
|
||||
|
||||
EOF
|
||||
|
||||
function test_return() {
|
||||
echo "In Funktion"
|
||||
return 42
|
||||
echo "Dies wird nicht ausgeführt"
|
||||
}
|
||||
|
||||
echo "Demo:"
|
||||
test_return
|
||||
echo "Return Code: $?"
|
||||
echo "Skript läuft weiter!"
|
||||
echo ""
|
||||
|
||||
# === GÜRTELPRÜFUNG ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
🥋 GÜRTELPRÜFUNG - GELBER GÜRTEL 💛
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Erstelle zwei Dateien:
|
||||
|
||||
1. 'biblio.sh' (Die Bibliothek):
|
||||
function abbrechen() {
|
||||
echo "Willst du fortsetzen? (j/n)"
|
||||
read eingabe
|
||||
if [ "$eingabe" = "n" ]; then
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
function summe() {
|
||||
local total=0
|
||||
for zahl in "$@"
|
||||
do
|
||||
total=$((total + zahl))
|
||||
done
|
||||
echo "$total"
|
||||
}
|
||||
|
||||
2. 'rechner.sh' (Das Hauptskript):
|
||||
#!/bin/bash
|
||||
source ./biblio.sh
|
||||
|
||||
echo "Berechne: 10 + 20 + 30"
|
||||
ergebnis=$(summe 10 20 30)
|
||||
echo "Ergebnis: $ergebnis"
|
||||
|
||||
abbrechen
|
||||
|
||||
echo "Weiter geht's!"
|
||||
|
||||
Führe aus: ./rechner.sh
|
||||
|
||||
EOF
|
||||
|
||||
read -p "Prüfung bestanden? (j/n): " pruefung
|
||||
|
||||
if [[ "$pruefung" =~ ^[jJyY]$ ]]; then
|
||||
cat << 'EOF'
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ 🎉 HERVORRAGEND! 🎉 ║
|
||||
║ Du hast den GELBEN GÜRTEL 💛 verdient! ║
|
||||
║ ║
|
||||
║ "Modularität ist der Schlüssel zur Meisterschaft." ║
|
||||
║ ║
|
||||
║ - BashPanda 🐼 ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
echo "🥋 Gelernt:"
|
||||
echo " ✅ Funktionen erstellen und aufrufen"
|
||||
echo " ✅ Parameter nutzen (\$1, \$@, \$#)"
|
||||
echo " ✅ source für Bibliotheken"
|
||||
echo " ✅ return vs exit"
|
||||
echo " ✅ local Variablen"
|
||||
echo ""
|
||||
echo "🎯 Letzter Gürtel: WEISS 🤍 (System: Jobs, Background)"
|
||||
else
|
||||
echo "🐼 'Funktionen sind wie Meditation - Geduld führt zur Erleuchtung.'"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "💬 bashpanda \"Wie erstelle ich eine Funktion mit Parametern?\""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
7
missions/dojo/gruener_guertel.meta.json
Normal file
7
missions/dojo/gruener_guertel.meta.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"icon": "💚",
|
||||
"title": "Grüner Gürtel - Die Mustererkennung",
|
||||
"description": "grep, regex, Pattern Matching - Erkenne die Ordnung im Chaos",
|
||||
"category": "dojo",
|
||||
"enabled": true
|
||||
}
|
||||
220
missions/dojo/gruener_guertel.sh
Executable file
220
missions/dojo/gruener_guertel.sh
Executable file
@@ -0,0 +1,220 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🐼 BashPanda Dojo - Grüner Gürtel 💚
|
||||
# Lehrt: grep, regex, Pattern Matching
|
||||
# Schwierigkeit: Fortgeschritten
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPT_DIR}/../../lib/waldwaechter.sh"
|
||||
|
||||
cat << 'EOF'
|
||||
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🐼 BASHPANDA DOJO - GRÜNER GÜRTEL 💚 ║
|
||||
║ ║
|
||||
║ "Muster erkennen ist der Weg zur Weisheit" ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 BashPanda nickt anerkennend. Du bist weit gekommen."
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
Der Grüne Gürtel lehrt dich MUSTERERKENNUNG.
|
||||
|
||||
Du wirst lernen:
|
||||
🎯 grep - Suchen in Dateien
|
||||
🎯 Regular Expressions (Regex) - Die Sprache der Muster
|
||||
🎯 grep -E - Extended Regex
|
||||
🎯 Praktische Anwendungen: Email, Datum, IP-Adressen
|
||||
|
||||
"Ein Meister sieht nicht nur was da ist, sondern erkennt das Muster."
|
||||
|
||||
EOF
|
||||
|
||||
read -p "➡️ Bereit für Mustererkennung? (j/n): " start
|
||||
[[ ! "$start" =~ ^[jJyY]$ ]] && echo "🐼 Das Muster wartet." && exit 0
|
||||
echo ""
|
||||
|
||||
# === PHASE 1: grep Basics ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 1: grep - Die Suche beginnt
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
grep durchsucht Text nach Mustern. Wie ein Adler, der Beute
|
||||
aus der Ferne erkennt.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Demo: Testdatei erstellen"
|
||||
cat > /tmp/waldwaechter.txt << 'DEMO'
|
||||
Maya-Eule ist weise
|
||||
FunkFox rappt im Beat
|
||||
DumboSQL vergisst nie
|
||||
BashPanda lehrt Geduld
|
||||
Schnippsi stylt alles
|
||||
DEMO
|
||||
|
||||
echo ""
|
||||
echo "Inhalt von waldwaechter.txt:"
|
||||
cat /tmp/waldwaechter.txt
|
||||
echo ""
|
||||
|
||||
echo "🥋 grep 'Fox' /tmp/waldwaechter.txt"
|
||||
grep 'Fox' /tmp/waldwaechter.txt
|
||||
echo ""
|
||||
|
||||
echo "🥋 grep -i 'bash' /tmp/waldwaechter.txt (case-insensitive)"
|
||||
grep -i 'bash' /tmp/waldwaechter.txt
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 grep Optionen:
|
||||
grep 'muster' datei Suche nach Muster
|
||||
grep -i 'muster' datei Ignore case
|
||||
grep -n 'muster' datei Zeige Zeilennummern
|
||||
grep -v 'muster' datei Invertiere (alles außer Muster)
|
||||
grep -c 'muster' datei Zähle Treffer
|
||||
grep -r 'muster' ordner/ Rekursiv in allen Dateien
|
||||
|
||||
EOF
|
||||
|
||||
# === PHASE 2: Regular Expressions ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 2: Regex - Die Sprache der Muster
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Regex ist wie die Geheimsprache der Textsuche.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Regex Zeichen:"
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
^ Zeilenanfang
|
||||
$ Zeilenende
|
||||
. Ein beliebiges Zeichen
|
||||
* 0 oder mehr Wiederholungen
|
||||
+ 1 oder mehr Wiederholungen
|
||||
? 0 oder 1 Wiederholung
|
||||
[abc] Eines der Zeichen a, b, c
|
||||
[0-9] Eine Ziffer
|
||||
[a-z] Ein Kleinbuchstabe
|
||||
|
||||
EOF
|
||||
|
||||
echo "🥋 Beispiele:"
|
||||
echo ""
|
||||
|
||||
echo "grep '^B' - Zeilen die mit B beginnen:"
|
||||
grep '^B' /tmp/waldwaechter.txt
|
||||
echo ""
|
||||
|
||||
echo "grep 't$' - Zeilen die mit t enden:"
|
||||
grep 't$' /tmp/waldwaechter.txt
|
||||
echo ""
|
||||
|
||||
# === PHASE 3: Email & Datum Erkennung ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 3: Praktische Muster - Email & Datum
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Email-Muster erkennen:"
|
||||
echo ""
|
||||
|
||||
cat > /tmp/emails.txt << 'DEMO'
|
||||
max@beispiel.de
|
||||
test@web.com
|
||||
invalid@
|
||||
not_an_email
|
||||
foo.bar@domain.co.uk
|
||||
DEMO
|
||||
|
||||
echo "Emails in Datei:"
|
||||
cat /tmp/emails.txt
|
||||
echo ""
|
||||
|
||||
echo "grep -E für Extended Regex:"
|
||||
echo "Email-Pattern: ^[a-zA-Z]+@[a-zA-Z]+\.[a-zA-Z]+$"
|
||||
echo ""
|
||||
|
||||
grep -E '^[a-zA-Z.]+@[a-zA-Z]+\.[a-zA-Z.]+$' /tmp/emails.txt
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 Nützliche Patterns:
|
||||
Email: ^[a-zA-Z.]+@[a-zA-Z]+\.[a-zA-Z.]+$
|
||||
Datum: ^[0-9]{2}\.[0-9]{2}\.[0-9]{4}$
|
||||
IP: ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$
|
||||
|
||||
EOF
|
||||
|
||||
# === GÜRTELPRÜFUNG ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
🥋 GÜRTELPRÜFUNG - GRÜNER GÜRTEL 💚
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Erstelle 'email_finder.sh' das:
|
||||
|
||||
1. Nimmt einen Dateinamen als Parameter: $1
|
||||
2. Sucht mit grep -E nach Email-Adressen
|
||||
3. Nutzt Pattern: ^[[:alpha:]]+(\.[[:alpha:]]+)*@[[:alpha:]]+(\.[[:alpha:]]+)+$
|
||||
4. Zeigt alle gefundenen Emails an
|
||||
5. Bonus: Zählt sie mit wc -l
|
||||
|
||||
Test-Datei erstellen:
|
||||
cat > emails_test.txt << 'END'
|
||||
maya@crumb.forest
|
||||
funkfox@beat.music
|
||||
invalid@
|
||||
test@
|
||||
dumbo@memory.database
|
||||
END
|
||||
|
||||
./email_finder.sh emails_test.txt
|
||||
|
||||
EOF
|
||||
|
||||
read -p "Prüfung bestanden? (j/n): " pruefung
|
||||
|
||||
if [[ "$pruefung" =~ ^[jJyY]$ ]]; then
|
||||
cat << 'EOF'
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ 🎉 AUSGEZEICHNET! 🎉 ║
|
||||
║ Du hast den GRÜNEN GÜRTEL 💚 verdient! ║
|
||||
║ ║
|
||||
║ "Wer Muster erkennt, erkennt die Ordnung im Chaos." ║
|
||||
║ ║
|
||||
║ - BashPanda 🐼 ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
echo "🥋 Gelernt:"
|
||||
echo " ✅ grep für Textsuche"
|
||||
echo " ✅ Regular Expressions"
|
||||
echo " ✅ Email/Datum Pattern"
|
||||
echo " ✅ grep -E Extended Regex"
|
||||
echo ""
|
||||
echo "🎯 Nächster Gürtel: GELB 💛 (Prozesse & Funktionen)"
|
||||
else
|
||||
echo "🐼 'Muster brauchen Zeit zum Erkennen.'"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "💬 bashpanda \"Wie funktioniert grep mit regex?\""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
7
missions/dojo/pinker_guertel.meta.json
Normal file
7
missions/dojo/pinker_guertel.meta.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"icon": "💖",
|
||||
"title": "Pinker Gürtel - Die Kontrolle",
|
||||
"description": "if/then/else, while/for loops, Arrays - Meistere den Fluss des Codes",
|
||||
"category": "dojo",
|
||||
"enabled": true
|
||||
}
|
||||
352
missions/dojo/pinker_guertel.sh
Executable file
352
missions/dojo/pinker_guertel.sh
Executable file
@@ -0,0 +1,352 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🐼 BashPanda Dojo - Pinker Gürtel 💖
|
||||
# Lehrt: if/then/else, while/for loops, Arrays, Arithmetik
|
||||
# Schwierigkeit: Fortgeschritten
|
||||
|
||||
# Source waldwaechter library for BashPanda
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPT_DIR}/../../lib/waldwaechter.sh"
|
||||
|
||||
cat << 'EOF'
|
||||
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🐼 BASHPANDA DOJO - PINKER GÜRTEL 💖 ║
|
||||
║ ║
|
||||
║ "Kontrolle kommt von innen, nicht von außen" ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 BashPanda verneigt sich tiefer als beim letzten Mal..."
|
||||
echo "🥋 Du bist zurückgekehrt. Das zeigt Entschlossenheit."
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
Der Pinke Gürtel lehrt dich KONTROLLE.
|
||||
|
||||
Du wirst lernen:
|
||||
🎯 if/then/else - Entscheidungen treffen
|
||||
🎯 while & for - Wiederholung mit Disziplin
|
||||
🎯 Arrays - Viele Werte, ein Container
|
||||
🎯 Arithmetik - $(( )) und Zahlen
|
||||
|
||||
"Der Fluss des Codes folgt deinen Bedingungen.
|
||||
Du bist der Meister über den Pfad."
|
||||
|
||||
EOF
|
||||
|
||||
read -p "➡️ Bereit für fortgeschrittenes Training? (j/n): " start
|
||||
echo ""
|
||||
|
||||
if [[ ! "$start" =~ ^[jJyY]$ ]]; then
|
||||
echo "🐼 Die Tür des Dojos steht immer offen."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# === PHASE 1: if/then/else - Entscheidungen ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 1: if/then/else - Der Pfad des Kriegers
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Im Kampf musst du schnell entscheiden: Angriff oder Verteidigung?
|
||||
In Bash entscheidest du mit if/then/else.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 BashPanda zeigt dir:"
|
||||
echo ""
|
||||
|
||||
cat << 'CODE'
|
||||
alter=25
|
||||
|
||||
if [ $alter -ge 18 ]
|
||||
then
|
||||
echo "Du bist volljährig"
|
||||
else
|
||||
echo "Du bist minderjährig"
|
||||
fi
|
||||
CODE
|
||||
|
||||
echo ""
|
||||
echo "Lass es uns live testen:"
|
||||
echo ""
|
||||
|
||||
echo "Wie alt bist du?"
|
||||
read alter
|
||||
|
||||
if [ $alter -ge 18 ]
|
||||
then
|
||||
echo "✅ Du bist volljährig - bereit für das Dojo!"
|
||||
else
|
||||
echo "🌱 Jung wie ein Bambussprössling - lerne mit Geduld."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 Vergleichsoperatoren:
|
||||
-eq Gleich (equal)
|
||||
-ne Nicht gleich (not equal)
|
||||
-gt Größer (greater than)
|
||||
-ge Größer oder gleich
|
||||
-lt Kleiner (less than)
|
||||
-le Kleiner oder gleich
|
||||
|
||||
Für Strings:
|
||||
[ "$a" = "$b" ] Strings sind gleich
|
||||
[ "$a" != "$b" ] Strings sind verschieden
|
||||
[ -z "$a" ] String ist leer
|
||||
[ -n "$a" ] String ist nicht leer
|
||||
|
||||
EOF
|
||||
|
||||
echo "🥋 Deine erste Kata:"
|
||||
echo ""
|
||||
echo "Erstelle 'datei_check.sh' das:"
|
||||
echo " - Fragt nach einem Dateinamen"
|
||||
echo " - Prüft ob die Datei existiert: [ -f \"\$datei\" ]"
|
||||
echo " - Gibt entsprechende Nachricht aus"
|
||||
echo ""
|
||||
|
||||
read -p "Bereit für Phase 2? (j/n): " phase1
|
||||
echo ""
|
||||
|
||||
# === PHASE 2: while Loop - Die Meditation ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 2: while - Die Meditation der Wiederholung
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Wie ein Mantra, das du wiederholst, läuft eine while-Schleife,
|
||||
bis die Bedingung nicht mehr wahr ist.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 BashPanda demonstriert:"
|
||||
echo ""
|
||||
|
||||
cat << 'CODE'
|
||||
zaehler=1
|
||||
|
||||
while [ $zaehler -le 5 ]
|
||||
do
|
||||
echo "Durchlauf: $zaehler"
|
||||
zaehler=$((zaehler + 1))
|
||||
done
|
||||
CODE
|
||||
|
||||
echo ""
|
||||
echo "Live-Demo:"
|
||||
echo ""
|
||||
|
||||
zaehler=1
|
||||
while [ $zaehler -le 5 ]
|
||||
do
|
||||
echo "🥋 Kata Durchlauf: $zaehler"
|
||||
sleep 0.5
|
||||
zaehler=$((zaehler + 1))
|
||||
done
|
||||
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 Wichtiges:
|
||||
- while [ bedingung ]; do
|
||||
- zaehler=$((zaehler + 1)) für Arithmetik
|
||||
- done am Ende
|
||||
- Achtung: Endlosschleifen vermeiden!
|
||||
|
||||
EOF
|
||||
|
||||
# === PHASE 3: for Loop - Der geordnete Kampf ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 3: for - Der geordnete Durchlauf
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Eine for-Schleife ist wie eine Kata-Sequenz:
|
||||
Du weißt genau welche Bewegungen kommen.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 BashPanda zeigt dir:"
|
||||
echo ""
|
||||
|
||||
cat << 'CODE'
|
||||
for name in Maya Tobi FunkFox BashPanda
|
||||
do
|
||||
echo "Hallo, $name!"
|
||||
done
|
||||
CODE
|
||||
|
||||
echo ""
|
||||
echo "Live-Demo:"
|
||||
echo ""
|
||||
|
||||
for name in Maya Tobi FunkFox BashPanda
|
||||
do
|
||||
echo "🐼 Begrüßung: Hallo, $name!"
|
||||
done
|
||||
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 for Varianten:
|
||||
for i in 1 2 3 4 5
|
||||
for datei in *.txt
|
||||
for zeile in $(cat datei.txt)
|
||||
for i in {1..10}
|
||||
|
||||
EOF
|
||||
|
||||
echo "🥋 Deine zweite Kata:"
|
||||
echo ""
|
||||
echo "Erstelle 'fibonacci.sh' das:"
|
||||
echo " - Fragt nach einer Zahl N"
|
||||
echo " - Gibt die ersten N Fibonacci-Zahlen aus"
|
||||
echo " - Nutze while und Arithmetik: a=$((a + b))"
|
||||
echo ""
|
||||
|
||||
read -p "Bereit für Phase 4? (j/n): " phase3
|
||||
echo ""
|
||||
|
||||
# === PHASE 4: Arrays - Viele Krieger, eine Armee ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 4: Arrays - Die Armee der Werte
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Ein Array ist wie eine Gruppe von Kriegern:
|
||||
Jeder hat seine Position, aber sie kämpfen zusammen.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 BashPanda demonstriert:"
|
||||
echo ""
|
||||
|
||||
cat << 'CODE'
|
||||
guertel=("Schwarz" "Pink" "Blau" "Gruen" "Gelb" "Weiss")
|
||||
|
||||
echo "Erster Gürtel: ${guertel[0]}"
|
||||
echo "Zweiter Gürtel: ${guertel[1]}"
|
||||
echo "Alle Gürtel: ${guertel[@]}"
|
||||
echo "Anzahl: ${#guertel[@]}"
|
||||
CODE
|
||||
|
||||
echo ""
|
||||
echo "Live-Demo:"
|
||||
echo ""
|
||||
|
||||
guertel=("Schwarz" "Pink" "Blau" "Gruen" "Gelb" "Weiss")
|
||||
|
||||
echo "🥋 Erster Gürtel: ${guertel[0]}"
|
||||
echo "🥋 Zweiter Gürtel: ${guertel[1]}"
|
||||
echo "🥋 Alle Gürtel: ${guertel[@]}"
|
||||
echo "🥋 Anzahl: ${#guertel[@]}"
|
||||
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 Array Operationen:
|
||||
arr=(1 2 3) Array erstellen
|
||||
${arr[0]} Erstes Element
|
||||
${arr[@]} Alle Elemente
|
||||
${#arr[@]} Anzahl Elemente
|
||||
arr+=(4) Element hinzufügen
|
||||
|
||||
Durchlauf:
|
||||
for element in "${arr[@]}"
|
||||
do
|
||||
echo "$element"
|
||||
done
|
||||
|
||||
EOF
|
||||
|
||||
# === PHASE 5: Die Gürtelprüfung ===
|
||||
|
||||
cat << 'EOF'
|
||||
|
||||
═══════════════════════════════════════════════════════════
|
||||
🥋 GÜRTELPRÜFUNG - PINKER GÜRTEL 💖
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Deine Aufgabe: Erstelle ein Skript 'summenspiel.sh' das:
|
||||
|
||||
1. Ein Array mit 5 Zahlen erstellt: zahlen=(10 20 30 40 50)
|
||||
2. Durch das Array iteriert (for-Schleife)
|
||||
3. Die Summe aller Zahlen berechnet
|
||||
4. Am Ende die Summe ausgibt
|
||||
|
||||
Bonus:
|
||||
5. Nutze if um zu prüfen ob die Summe > 100 ist
|
||||
6. Gib entsprechende Nachricht aus
|
||||
|
||||
Beispiel-Ausgabe:
|
||||
Zahlen: 10 20 30 40 50
|
||||
Summe: 150
|
||||
✅ Summe ist größer als 100!
|
||||
|
||||
EOF
|
||||
|
||||
echo "💡 Hilfe:"
|
||||
echo " - summe=0 zum Initialisieren"
|
||||
echo " - summe=\$((summe + zahl)) zum Addieren"
|
||||
echo " - for zahl in \"\${zahlen[@]}\""
|
||||
echo ""
|
||||
|
||||
read -p "Hast du die Prüfung absolviert? (j/n): " pruefung
|
||||
echo ""
|
||||
|
||||
if [[ "$pruefung" =~ ^[jJyY]$ ]]; then
|
||||
cat << 'EOF'
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🎉 AUSGEZEICHNET! 🎉 ║
|
||||
║ ║
|
||||
║ Du hast den PINKEN GÜRTEL 💖 verdient! ║
|
||||
║ ║
|
||||
║ "Kontrolle über den Code heißt Kontrolle ║
|
||||
║ über deine Gedanken." ║
|
||||
║ ║
|
||||
║ - BashPanda 🐼 ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
|
||||
echo "🥋 Was du gemeistert hast:"
|
||||
echo " ✅ if/then/else Entscheidungen"
|
||||
echo " ✅ while Schleifen mit Bedingungen"
|
||||
echo " ✅ for Schleifen für Iteration"
|
||||
echo " ✅ Arrays erstellen und nutzen"
|
||||
echo " ✅ Arithmetik mit \$(( ))"
|
||||
echo ""
|
||||
echo "🎯 Nächster Gürtel: BLAU 💙 (Textverarbeitung: sed, case)"
|
||||
echo ""
|
||||
|
||||
# Small easter egg
|
||||
echo "🎋 BashPanda sagt:"
|
||||
bashpanda "Was ist die Weisheit hinter Schleifen und Wiederholung im Code?"
|
||||
|
||||
else
|
||||
cat << 'EOF'
|
||||
🐼 "Kontrolle braucht Übung, wie ein Baum Zeit zum Wachsen braucht.
|
||||
Nimm dir die Zeit. Kehre zurück wenn du bereit bist."
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "💬 Fragen? Rufe den Meister:"
|
||||
echo " bashpanda \"Wie funktioniert eine while-Schleife?\""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
7
missions/dojo/schwarzer_guertel.meta.json
Normal file
7
missions/dojo/schwarzer_guertel.meta.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"icon": "🖤",
|
||||
"title": "Schwarzer Gürtel - Die Grundlagen",
|
||||
"description": "echo, printf, Variablen, read - Der erste Schritt auf dem Weg des Bash-Meisters",
|
||||
"category": "dojo",
|
||||
"enabled": true
|
||||
}
|
||||
300
missions/dojo/schwarzer_guertel.sh
Executable file
300
missions/dojo/schwarzer_guertel.sh
Executable file
@@ -0,0 +1,300 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🐼 BashPanda Dojo - Schwarzer Gürtel 🖤
|
||||
# Lehrt: echo, printf, Variablen, Benutzereingaben
|
||||
# Schwierigkeit: Anfänger
|
||||
|
||||
# Source waldwaechter library for BashPanda
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPT_DIR}/../../lib/waldwaechter.sh"
|
||||
|
||||
cat << 'EOF'
|
||||
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🐼 BASHPANDA DOJO - SCHWARZER GÜRTEL 🖤 ║
|
||||
║ ║
|
||||
║ "Der Weg des Codes beginnt mit einem einzigen echo" ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 BashPanda verneigt sich vor dir..."
|
||||
echo "🥋 Willkommen im Dojo, junger Schüler."
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
Der Schwarze Gürtel ist der erste Schritt auf dem Weg des Bash-Meisters.
|
||||
|
||||
Du wirst lernen:
|
||||
🎯 echo & printf - Die Stimme des Terminals
|
||||
🎯 Variablen - Container für Wissen
|
||||
🎯 read - Den Dialog mit dem Nutzer
|
||||
🎯 ANSI Codes - Farbe ins Terminal bringen
|
||||
|
||||
"Eine Reise von tausend Befehlen beginnt mit einem einzigen Zeichen."
|
||||
|
||||
EOF
|
||||
|
||||
read -p "➡️ Bereit für dein erstes Training? (j/n): " start
|
||||
echo ""
|
||||
|
||||
if [[ ! "$start" =~ ^[jJyY]$ ]]; then
|
||||
echo "🐼 Der Meister wartet geduldig auf deine Rückkehr."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# === PHASE 1: echo - Die Stimme des Terminals ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 1: echo - Die Stimme des Terminals
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Wie ein Kampfschrei im Dojo, so ist 'echo' die grundlegendste
|
||||
Ausgabe im Terminal.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 BashPanda zeigt dir:"
|
||||
echo ""
|
||||
echo " echo 'Hallo Welt'"
|
||||
echo ""
|
||||
echo "Resultat:"
|
||||
echo 'Hallo Welt'
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 WICHTIG:
|
||||
- Einfache Anführungszeichen ('): Text wird exakt ausgegeben
|
||||
- Doppelte Anführungszeichen ("): Variablen werden ersetzt
|
||||
- echo -e: Aktiviert ANSI Escape-Sequenzen
|
||||
|
||||
EOF
|
||||
|
||||
echo "🥋 Deine erste Kata (Übung):"
|
||||
echo ""
|
||||
echo "1. Öffne ein neues Terminal"
|
||||
echo "2. Tippe: echo 'Ich bin ein Bash-Schüler'"
|
||||
echo "3. Drücke Enter"
|
||||
echo ""
|
||||
|
||||
read -p "Hast du es probiert? (j/n): " phase1
|
||||
echo ""
|
||||
|
||||
if [[ "$phase1" =~ ^[jJyY]$ ]]; then
|
||||
echo "✅ Gut! Die erste Technik sitzt."
|
||||
else
|
||||
echo "🐼 'Ohne Übung kein Fortschritt. Probiere es später aus.'"
|
||||
fi
|
||||
|
||||
# === PHASE 2: printf & ANSI Codes ===
|
||||
|
||||
cat << 'EOF'
|
||||
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 2: printf & ANSI Codes - Die Kunst der Formatierung
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
printf ist wie echo, aber mit mehr Kontrolle.
|
||||
ANSI Codes sind wie Chi - sie geben dem Text Kraft und Farbe.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 BashPanda demonstriert:"
|
||||
echo ""
|
||||
echo " echo -e '\\e[1mFett\\e[22m und \\e[4munterstrichen\\e[24m'"
|
||||
echo ""
|
||||
echo "Resultat:"
|
||||
echo -e '\e[1mFett\e[22m und \e[4munterstrichen\e[24m'
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
📖 Wichtige ANSI Codes:
|
||||
\e[1m - Fett
|
||||
\e[22m - Fett zurücksetzen
|
||||
\e[4m - Unterstrichen
|
||||
\e[24m - Unterstrichen zurücksetzen
|
||||
\e[32m - Grüne Farbe
|
||||
\e[0m - Alle Formatierungen zurücksetzen
|
||||
|
||||
EOF
|
||||
|
||||
echo "🥋 Deine zweite Kata:"
|
||||
echo ""
|
||||
echo "Erstelle eine Datei 'farbtest.sh' mit:"
|
||||
echo ""
|
||||
cat << 'CODE'
|
||||
#!/bin/bash
|
||||
echo -e "\e[32mGrün wie Bambus\e[0m"
|
||||
echo -e "\e[1m\e[33mGelb und fett wie die Sonne\e[0m"
|
||||
echo -e "\e[4mUnterstrichen wie ein Pfad\e[0m"
|
||||
CODE
|
||||
echo ""
|
||||
echo "Dann: chmod +x farbtest.sh && ./farbtest.sh"
|
||||
echo ""
|
||||
|
||||
read -p "Möchtest du fortfahren? (j/n): " phase2
|
||||
echo ""
|
||||
|
||||
# === PHASE 3: Variablen - Container für Wissen ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 3: Variablen - Container für Wissen
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Eine Variable ist wie ein Bambus - biegsam, kann viel tragen,
|
||||
und wächst mit der Zeit.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 BashPanda zeigt dir:"
|
||||
echo ""
|
||||
|
||||
cat << 'CODE'
|
||||
name="Kung Fu Meister"
|
||||
echo "Hallo, $name"
|
||||
echo "Mein Name ist: ${name}"
|
||||
CODE
|
||||
|
||||
echo ""
|
||||
echo "Resultat:"
|
||||
name="Kung Fu Meister"
|
||||
echo "Hallo, $name"
|
||||
echo "Mein Name ist: ${name}"
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 Regeln für Variablen:
|
||||
- Keine Leerzeichen um das '=' Zeichen!
|
||||
- Variablennamen: Buchstaben, Zahlen, Unterstriche
|
||||
- Zugriff mit $variable oder ${variable}
|
||||
|
||||
EOF
|
||||
|
||||
echo "🥋 Deine dritte Kata:"
|
||||
echo ""
|
||||
echo "Erstelle 'variablen_test.sh':"
|
||||
echo ""
|
||||
cat << 'CODE'
|
||||
#!/bin/bash
|
||||
guertel="Schwarz"
|
||||
meister="BashPanda"
|
||||
echo "Ich trainiere für den ${guertel}en Gürtel."
|
||||
echo "Mein Meister ist $meister."
|
||||
CODE
|
||||
echo ""
|
||||
|
||||
read -p "Bereit für die letzte Phase? (j/n): " phase3
|
||||
echo ""
|
||||
|
||||
# === PHASE 4: read - Der Dialog mit dem Nutzer ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 4: read - Der Dialog mit dem Nutzer
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Ein Meister hört zu. Mit 'read' gibst du dem Nutzer eine Stimme.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 BashPanda zeigt dir:"
|
||||
echo ""
|
||||
|
||||
cat << 'CODE'
|
||||
echo "Wie heißt du?"
|
||||
read name
|
||||
echo "Willkommen, $name!"
|
||||
CODE
|
||||
|
||||
echo ""
|
||||
echo "Lass es uns live testen:"
|
||||
echo ""
|
||||
echo "Wie heißt du?"
|
||||
read name
|
||||
echo "Willkommen im Dojo, $name! 🐼"
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 read Optionen:
|
||||
read name - Speichert Eingabe in $name
|
||||
read -p "Frage: " - Zeigt Prompt vor Eingabe
|
||||
read -s password - Silent mode (für Passwörter)
|
||||
|
||||
EOF
|
||||
|
||||
# === PHASE 5: Die Gürtelprüfung ===
|
||||
|
||||
cat << 'EOF'
|
||||
|
||||
═══════════════════════════════════════════════════════════
|
||||
🥋 GÜRTELPRÜFUNG - SCHWARZER GÜRTEL 🖤
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Deine Aufgabe: Erstelle ein Skript 'begruessung.sh' das:
|
||||
|
||||
1. Den Nutzer nach seinem Namen fragt
|
||||
2. Nach seinem Lieblings-Essen fragt
|
||||
3. Eine farbige Begrüßung ausgibt mit:
|
||||
- Namen in GRÜN
|
||||
- Essen in GELB
|
||||
- "Willkommen im Dojo" in FETT
|
||||
|
||||
Beispiel-Ausgabe:
|
||||
Willkommen im Dojo!
|
||||
Name: Max (in grün)
|
||||
Lieblingsessen: Nudeln (in gelb)
|
||||
|
||||
EOF
|
||||
|
||||
echo "💡 Hilfestellung: Nutze echo -e, read -p, Variablen und ANSI Codes"
|
||||
echo ""
|
||||
echo "Wenn du fertig bist, führe dein Skript aus und zeige es BashPanda!"
|
||||
echo ""
|
||||
|
||||
read -p "Hast du die Prüfung absolviert? (j/n): " pruefung
|
||||
echo ""
|
||||
|
||||
if [[ "$pruefung" =~ ^[jJyY]$ ]]; then
|
||||
cat << 'EOF'
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🎉 GLÜCKWUNSCH! 🎉 ║
|
||||
║ ║
|
||||
║ Du hast den SCHWARZEN GÜRTEL 🖤 verdient! ║
|
||||
║ ║
|
||||
║ "Der erste Schritt ist getan. ║
|
||||
║ Tausend weitere liegen vor dir." ║
|
||||
║ ║
|
||||
║ - BashPanda 🐼 ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
|
||||
echo "🥋 Was du gelernt hast:"
|
||||
echo " ✅ echo & printf für Ausgaben"
|
||||
echo " ✅ ANSI Codes für Formatierung"
|
||||
echo " ✅ Variablen erstellen und nutzen"
|
||||
echo " ✅ read für Benutzereingaben"
|
||||
echo ""
|
||||
echo "🎯 Nächster Gürtel: PINK 💖 (Kontrolle: if/then, Arrays)"
|
||||
echo ""
|
||||
else
|
||||
cat << 'EOF'
|
||||
🐼 "Es ist keine Schande, mehr Zeit zu brauchen.
|
||||
Auch der größte Meister war einst ein Anfänger.
|
||||
Übe weiter, und komm zurück wenn du bereit bist."
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "💬 Fragen? Rufe den Meister:"
|
||||
echo " bashpanda \"Wie funktioniert echo?\""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
7
missions/dojo/weisser_guertel.meta.json
Normal file
7
missions/dojo/weisser_guertel.meta.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"icon": "🤍",
|
||||
"title": "Weisser Gürtel - Die Meisterschaft",
|
||||
"description": "Background Jobs, Prozesse, parallel processing - Der Weg des Meisters",
|
||||
"category": "dojo",
|
||||
"enabled": true
|
||||
}
|
||||
313
missions/dojo/weisser_guertel.sh
Executable file
313
missions/dojo/weisser_guertel.sh
Executable file
@@ -0,0 +1,313 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🐼 BashPanda Dojo - Weisser Gürtel 🤍
|
||||
# Lehrt: Background Jobs, Processes, ps, jobs, &
|
||||
# Schwierigkeit: Meister
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPT_DIR}/../../lib/waldwaechter.sh"
|
||||
|
||||
cat << 'EOF'
|
||||
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🐼 BASHPANDA DOJO - WEISSER GÜRTEL 🤍 ║
|
||||
║ ║
|
||||
║ "Der Meister kontrolliert nicht nur Code, ║
|
||||
║ sondern auch Prozesse" ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 BashPanda steht auf. Er verneigt sich als Ebenbürtiger."
|
||||
echo "🥋 Du bist bereit für die letzte Lehre."
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
Der Weisse Gürtel lehrt dich PROZESS-KONTROLLE.
|
||||
|
||||
Du wirst lernen:
|
||||
🎯 & - Jobs im Hintergrund starten
|
||||
🎯 jobs - Aktive Jobs anzeigen
|
||||
🎯 ps - Prozesse anzeigen
|
||||
🎯 kill - Prozesse beenden
|
||||
🎯 wait - Auf Prozesse warten
|
||||
|
||||
"Ein Meister lässt Prozesse für sich arbeiten,
|
||||
während er meditiert."
|
||||
|
||||
EOF
|
||||
|
||||
read -p "➡️ Bereit für die Meisterprüfung? (j/n): " start
|
||||
[[ ! "$start" =~ ^[jJyY]$ ]] && echo "🐼 Der Weg endet nie." && exit 0
|
||||
echo ""
|
||||
|
||||
# === PHASE 1: Background Jobs mit & ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 1: & - Hintergrund-Prozesse
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Mit & startest du einen Prozess im Hintergrund.
|
||||
Das Terminal bleibt frei für weitere Befehle.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Live Demo:"
|
||||
echo ""
|
||||
|
||||
echo "Starte: sleep 5 &"
|
||||
sleep 5 &
|
||||
JOB_PID=$!
|
||||
echo "Job gestartet mit PID: $JOB_PID"
|
||||
echo ""
|
||||
|
||||
echo "Terminal ist frei! Ich kann weiter arbeiten."
|
||||
echo "Der Job läuft im Hintergrund..."
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 Background Syntax:
|
||||
command & Starte im Hintergrund
|
||||
$! PID des letzten Background-Jobs
|
||||
jobs Zeige alle aktiven Jobs
|
||||
fg %1 Bring Job 1 in Vordergrund
|
||||
bg %1 Sende Job 1 in Hintergrund
|
||||
|
||||
EOF
|
||||
|
||||
# === PHASE 2: jobs & ps ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 2: jobs & ps - Übersicht behalten
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Demo: Mehrere Jobs starten"
|
||||
echo ""
|
||||
|
||||
sleep 3 &
|
||||
sleep 4 &
|
||||
sleep 5 &
|
||||
|
||||
echo "jobs zeigt alle Jobs dieser Shell:"
|
||||
jobs
|
||||
echo ""
|
||||
|
||||
echo "ps zeigt alle deine Prozesse:"
|
||||
ps aux | grep $USER | head -5
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 Prozess-Befehle:
|
||||
jobs Jobs der aktuellen Shell
|
||||
ps aux Alle Prozesse (detailliert)
|
||||
ps aux | grep X Suche Prozess X
|
||||
pgrep name Finde PID von Prozess
|
||||
pkill name Beende Prozess nach Namen
|
||||
|
||||
EOF
|
||||
|
||||
# === PHASE 3: wait - Auf Prozesse warten ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 3: wait - Synchronisation
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
wait wartet bis ein Background-Job fertig ist.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Live Demo:"
|
||||
echo ""
|
||||
|
||||
cat << 'CODE'
|
||||
echo "Starte Job..."
|
||||
sleep 2 &
|
||||
PID=$!
|
||||
echo "Warte auf Job $PID..."
|
||||
wait $PID
|
||||
echo "Job ist fertig!"
|
||||
CODE
|
||||
|
||||
echo ""
|
||||
echo "Ausführung:"
|
||||
echo "Starte Job..."
|
||||
sleep 2 &
|
||||
PID=$!
|
||||
echo "Warte auf Job $PID..."
|
||||
wait $PID
|
||||
echo "✅ Job ist fertig!"
|
||||
echo ""
|
||||
|
||||
cat << 'EOF'
|
||||
💡 wait Verwendung:
|
||||
wait Warte auf ALLE Background-Jobs
|
||||
wait $PID Warte auf spezifischen Job
|
||||
wait %1 Warte auf Job-Nummer 1
|
||||
|
||||
EOF
|
||||
|
||||
# === PHASE 4: Praktisches Beispiel ===
|
||||
|
||||
cat << 'EOF'
|
||||
═══════════════════════════════════════════════════════════
|
||||
📚 PHASE 4: Parallel Processing - Die Macht
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Mehrere Tasks parallel ausführen, dann auf alle warten.
|
||||
|
||||
EOF
|
||||
|
||||
echo "🐼 Demo: 3 Tasks parallel"
|
||||
echo ""
|
||||
|
||||
cat << 'CODE'
|
||||
function task() {
|
||||
echo "Task $1 startet..."
|
||||
sleep 2
|
||||
echo "Task $1 fertig!"
|
||||
}
|
||||
|
||||
task 1 &
|
||||
task 2 &
|
||||
task 3 &
|
||||
|
||||
wait
|
||||
echo "Alle Tasks abgeschlossen!"
|
||||
CODE
|
||||
|
||||
echo ""
|
||||
echo "Ausführung:"
|
||||
|
||||
function task() {
|
||||
echo "🥋 Task $1 startet..."
|
||||
sleep 1
|
||||
echo "✅ Task $1 fertig!"
|
||||
}
|
||||
|
||||
task 1 &
|
||||
task 2 &
|
||||
task 3 &
|
||||
|
||||
wait
|
||||
echo "🐼 Alle Tasks abgeschlossen!"
|
||||
echo ""
|
||||
|
||||
# === DIE MEISTERPRÜFUNG ===
|
||||
|
||||
cat << 'EOF'
|
||||
|
||||
═══════════════════════════════════════════════════════════
|
||||
🥋 MEISTERPRÜFUNG - WEISSER GÜRTEL 🤍
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Deine finale Aufgabe: Erstelle 'parallel_processor.sh'
|
||||
|
||||
Das Skript soll:
|
||||
|
||||
1. Eine Funktion 'process_file' definieren:
|
||||
- Nimmt Dateiname als Parameter
|
||||
- Zählt Wörter mit wc -w
|
||||
- Schreibt Ergebnis in \${datei}.count
|
||||
|
||||
2. 5 Test-Dateien erstellen:
|
||||
echo "Test Inhalt" > file1.txt
|
||||
(für file1 bis file5)
|
||||
|
||||
3. Alle 5 parallel verarbeiten:
|
||||
for file in file*.txt
|
||||
do
|
||||
process_file "$file" &
|
||||
done
|
||||
|
||||
4. Mit wait auf alle warten
|
||||
|
||||
5. Ergebnisse ausgeben:
|
||||
cat file*.count
|
||||
|
||||
Bonuspunkte:
|
||||
- Nutze jobs um zu zeigen wie viele laufen
|
||||
- Speichere PIDs in Array
|
||||
- Prüfe mit $? ob Jobs erfolgreich waren
|
||||
|
||||
EOF
|
||||
|
||||
echo "💡 Dies kombiniert ALLES was du gelernt hast:"
|
||||
echo " - Funktionen (Gelb)"
|
||||
echo " - Arrays & Schleifen (Pink)"
|
||||
echo " - Background Jobs & wait (Weiss)"
|
||||
echo ""
|
||||
|
||||
read -p "Hast du die Meisterprüfung bestanden? (j/n): " pruefung
|
||||
|
||||
if [[ "$pruefung" =~ ^[jJyY]$ ]]; then
|
||||
cat << 'EOF'
|
||||
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🏆 MEISTERSCHAFT ERREICHT! 🏆 ║
|
||||
║ ║
|
||||
║ Du hast den WEISSEN GÜRTEL 🤍 verdient! ║
|
||||
║ ║
|
||||
║ DU BIST NUN EIN BASH-MEISTER! ║
|
||||
║ ║
|
||||
║ "Der Weg des Meisters endet nie. ║
|
||||
║ Mit jedem Tag lernst du etwas Neues. ║
|
||||
║ Lehre nun andere, was du gelernt hast." ║
|
||||
║ ║
|
||||
║ - BashPanda 🐼 ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
echo "🥋 DEINE REISE DURCH DAS DOJO:"
|
||||
echo ""
|
||||
echo " 🖤 Schwarzer Gürtel: echo, Variablen, read"
|
||||
echo " 💖 Pinker Gürtel: if/then, Schleifen, Arrays"
|
||||
echo " 💙 Blauer Gürtel: sed, case, bc"
|
||||
echo " 💚 Grüner Gürtel: grep, regex, Pattern"
|
||||
echo " 💛 Gelber Gürtel: Funktionen, source"
|
||||
echo " 🤍 Weisser Gürtel: Background Jobs, Prozesse"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "🌲 WILLKOMMEN IN DER CRUMBCREW! 🌲"
|
||||
echo ""
|
||||
echo " Du kannst nun:"
|
||||
echo " - Alle 18 Waldwächter befehligen"
|
||||
echo " - Eigene Bash-Skripte meistern"
|
||||
echo " - Komplexe Missions im Crumbforest lösen"
|
||||
echo ""
|
||||
echo "🎯 Nächste Schritte:"
|
||||
echo " - Erkunde missions/robots/ (Hardware-Projekte)"
|
||||
echo " - Nutze ./crumb-mission-selector.sh (Option 9: CrumbCrew)"
|
||||
echo " - Erstelle eigene Skripte und teile sie!"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "🐼 BashPanda sagt zum Abschied:"
|
||||
echo ""
|
||||
|
||||
bashpanda "Was ist die Weisheit eines Bash-Meisters?"
|
||||
|
||||
else
|
||||
cat << 'EOF'
|
||||
🐼 "Der weisse Gürtel ist der Anfang, nicht das Ende.
|
||||
Übe weiter. Der Weg des Meisters ist niemals vollendet."
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "💬 bashpanda \"Was sind Background-Prozesse?\""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user