-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchef_pro.sh
More file actions
150 lines (130 loc) · 4.21 KB
/
chef_pro.sh
File metadata and controls
150 lines (130 loc) · 4.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/bin/bash
# chef.sh — Minimal recipe executor for Linux pros
# Usage:
# ./chef.sh <recipe> → cook recipe
# ./chef.sh list [q] → list recipes (optional search)
# Format: .inf files with [section], ingredients=..., cleanups=...
set -euo pipefail
SELF_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
RECIPE_PATHS=("$SELF_PATH/рецепты" "$SELF_PATH/книги_рецептов" "$SELF_PATH")
CLIENT=""
RECIPE_FILE=""
declare -A RECIPE_INGREDIENTS RECIPE_CLEANUPS
# === SUPPORTED DISTROS ===
declare -A DISTRO_MAPPING=(
["debian"]="apt" ["ubuntu"]="apt" ["linuxmint"]="apt" ["astra"]="apt" ["kali"]="apt"
["alt"]="alt" ["altlinux"]="alt" ["simply"]="apt"
["redos"]="dnf" ["fedora"]="dnf" ["rhel"]="dnf" ["centos"]="dnf"
["arch"]="pacman" ["manjaro"]="pacman" ["endeavouros"]="pacman"
["opensuse"]="zypper" ["suse"]="zypper"
)
declare -A PKGMGR=(
["apt"]="apt-get install -y"
["alt"]="apt-get install -y"
["dnf"]="dnf install -y"
["pacman"]="pacman -S --noconfirm"
["zypper"]="zypper install -y"
)
declare -A PKGREM=(
["apt"]="apt-get remove -y --purge"
["alt"]="apt-get remove -y --purge"
["dnf"]="dnf remove -y"
["pacman"]="pacman -Rns --noconfirm"
["zypper"]="zypper remove -y"
)
# === CORE FUNCTIONS ===
detect_client() {
[[ -f /etc/os-release ]] || { echo "error: /etc/os-release not found" >&2; exit 1; }
source /etc/os-release
CLIENT="${ID,,}"
[[ -n "${DISTRO_MAPPING[$CLIENT]:-}" ]] || { echo "error: unsupported distro '$CLIENT'" >&2; exit 1; }
}
find_recipe() {
local pattern="*${CLIENT}*.inf"
for path in "${RECIPE_PATHS[@]}"; do
[[ -d "$path" ]] || continue
while IFS= read -rd '' f; do
RECIPE_FILE="$f"
return 0
done < <(find "$path" -maxdepth 1 -name "$pattern" -type f -print0 2>/dev/null)
done
echo "error: no recipe for '$CLIENT'" >&2
exit 1
}
load_recipes() {
local sec=""
while IFS= read -r line || [[ -n "$line" ]]; do
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
if [[ "$line" =~ ^\[([a-zA-Z0-9_-]+)\]$ ]]; then
sec="${BASH_REMATCH[1]}"
elif [[ -n "$sec" && "$line" =~ ^ingredients[[:space:]]*=[[:space:]]*(.*) ]]; then
RECIPE_INGREDIENTS["$sec"]="${BASH_REMATCH[1]}"
elif [[ -n "$sec" && "$line" =~ ^cleanups[[:space:]]*=[[:space:]]*(.*) ]]; then
RECIPE_CLEANUPS["$sec"]="${BASH_REMATCH[1]}"
fi
done < "$RECIPE_FILE"
}
run_with_privileges() {
if [[ $EUID -eq 0 ]]; then "$@"; return; fi
if command -v sudo >/dev/null; then sudo "$@"; return; fi
echo "error: root required, sudo not found" >&2
exit 1
}
install_pkgs() {
local pkgs="$1"
[[ -z "$pkgs" ]] && return
local mgr="${PKGMGR[${DISTRO_MAPPING[$CLIENT]}]}"
run_with_privileges ${mgr} $pkgs
}
remove_pkgs() {
local pkgs="$1"
[[ -z "$pkgs" ]] && return
local mgr="${PKGREM[${DISTRO_MAPPING[$CLIENT]}]}"
run_with_privileges ${mgr} $pkgs
}
# === LIST COMMAND ===
cmd_list() {
local search="${1:-}"
detect_client
find_recipe
load_recipes
local found=()
for key in "${!RECIPE_INGREDIENTS[@]}" "${!RECIPE_CLEANUPS[@]}"; do
[[ -n "${RECIPE_INGREDIENTS[$key]:-}${RECIPE_CLEANUPS[$key]:-}" ]] && found+=("$key")
done
# Уникальные ключи
readarray -t unique < <(printf '%s\n' "${found[@]}" | sort -u)
if [[ -n "$search" ]]; then
readarray -t unique < <(printf '%s\n' "${unique[@]}" | grep -i "$search")
fi
if [[ ${#unique[@]} -eq 0 ]]; then
echo "no recipes found"
return
fi
for r in "${unique[@]}"; do
echo "$r"
done
}
# === COOK COMMAND ===
cmd_cook() {
local query="$1"
[[ -z "$query" ]] && { echo "usage: $0 <recipe> | list [search]" >&2; exit 1; }
detect_client
find_recipe
load_recipes
if [[ -z "${RECIPE_INGREDIENTS[$query]:-}" && -z "${RECIPE_CLEANUPS[$query]:-}" ]]; then
echo "error: recipe '$query' not found" >&2
exit 2
fi
remove_pkgs "${RECIPE_CLEANUPS[$query]:-}"
install_pkgs "${RECIPE_INGREDIENTS[$query]:-}"
}
# === MAIN ===
case "${1:-}" in
list)
cmd_list "$2"
;;
*)
cmd_cook "$1"
;;
esac