Last active 14 hours ago

Утилита для управления виртуальными хостами NGINX в системах с организацией конфигурации через sites-available/sites-enabled.

Revision 82bb99366fac0a5d315efd681463059d69a024c0

vhostmanage.sh Raw
1#!/bin/bash
2VERSION='1.1'
3
4### Конфигурация ###
5SEARCH_EXTENSION="*" # Можно изменить на "*" для поиска всех файлов
6SITES_AVAILABLE="/etc/nginx/sites-available"
7SITES_ENABLED="/etc/nginx/sites-enabled"
8SITES_ORDER_DISABLED_FIRST=1 # 1 - выключенные первыми, 0 - включенные первыми
9
10### Стили вывода ###
11GREEN='\033[0;32m'
12RED='\033[0;31m'
13YELLOW='\033[1;33m'
14NC='\033[0m' # No Color
15
16### Справка ###
17show_help() {
18 echo ""
19 echo -e "${YELLOW}VHostManage version $VERSION${NC}"
20 echo -e "(c) Karel Wintersky + Claude Sonnet, 2025-2026"
21 echo ""
22 echo -e "${YELLOW}Использование:${NC}"
23 echo " vhostmanage - Информация о версии и список всех сайтов"
24 echo " vhostmanage list - Список всех сайтов"
25 echo " vhostmanage list enabled - Список только включенных сайтов"
26 echo " vhostmanage list disabled - Список только выключенных сайтов"
27 echo " vhostmanage enable <site> [link_name] - Включить сайт"
28 echo " vhostmanage disable <site> - Выключить сайт"
29 echo " vhostmanage help - Показать эту справку"
30 echo -e "\n${YELLOW}Настройки:${NC}"
31 echo " Измените SEARCH_EXTENSION в скрипте"
32 echo " Доступные значения: conf (по умолчанию) или * (все файлы)"
33}
34
35### Проверка прав ###
36check_root() {
37 if [ "$(id -u)" -ne 0 ]; then
38 echo -e "${RED}ВАЖНО: для выполнения команд enable/disable требуется root (используйте sudo)${NC}" >&2
39# exit 1
40 fi
41}
42
43### Получить реальный путь из симлинка ###
44get_available_path() {
45 local enabled_link="$1"
46 readlink -f "$enabled_link" | sed "s|^$SITES_AVAILABLE/||"
47}
48
49### Поиск конфигов ###
50find_configs() {
51 local search_pattern="*.$SEARCH_EXTENSION"
52 [ "$SEARCH_EXTENSION" = "*" ] && search_pattern="*"
53
54 find "$SITES_AVAILABLE" -type f -name "$search_pattern" | while read -r file; do
55 echo "${file#$SITES_AVAILABLE/}"
56 done
57}
58
59### Проверка включен ли сайт ###
60is_enabled() {
61 local site_path="$1"
62 find "$SITES_ENABLED" -type l | while read -r link; do
63 if [ "$(get_available_path "$link")" = "$site_path" ]; then
64 echo "1"
65 return
66 fi
67 done | grep -q "1"
68}
69
70### Получить имя симлинка для сайта ###
71get_enabled_name() {
72 local site_path="$1"
73 find "$SITES_ENABLED" -type l | while read -r link; do
74 if [ "$(get_available_path "$link")" = "$site_path" ]; then
75 basename "$link"
76 return
77 fi
78 done
79}
80
81### Вывод списка ###
82list_sites() {
83 local filter="$1" # all, enabled, disabled
84
85 if [ "$filter" != "enabled" ] && [ "$filter" != "disabled" ]; then
86 filter="all"
87 fi
88
89 # Собираем сайты в массивы
90 local enabled_sites=()
91 local disabled_sites=()
92
93 while IFS= read -r rel_path; do
94 if is_enabled "$rel_path"; then
95 enabled_sites+=("$rel_path")
96 else
97 disabled_sites+=("$rel_path")
98 fi
99 done < <(find_configs)
100
101 # Сортируем массивы
102 IFS=$'\n' enabled_sites=($(sort <<<"${enabled_sites[*]}"))
103 IFS=$'\n' disabled_sites=($(sort <<<"${disabled_sites[*]}"))
104 unset IFS
105
106 # Выводим в зависимости от фильтра и порядка
107 if [ "$filter" = "all" ]; then
108 if [ "$SITES_ORDER_DISABLED_FIRST" -eq 1 ]; then
109 # Сначала выключенные
110 for rel_path in "${disabled_sites[@]}"; do
111 echo -e "${RED}[disabled]${NC} $rel_path"
112 done
113 for rel_path in "${enabled_sites[@]}"; do
114 local enabled_name=$(get_enabled_name "$rel_path")
115 local base_name=$(basename "$rel_path")
116 if [ "$enabled_name" != "$base_name" ]; then
117 echo -e "${GREEN}[enabled]${NC} $rel_path (как $enabled_name)"
118 else
119 echo -e "${GREEN}[enabled]${NC} $rel_path"
120 fi
121 done
122 else
123 # Сначала включенные
124 for rel_path in "${enabled_sites[@]}"; do
125 local enabled_name=$(get_enabled_name "$rel_path")
126 local base_name=$(basename "$rel_path")
127 if [ "$enabled_name" != "$base_name" ]; then
128 echo -e "${GREEN}[enabled]${NC} $rel_path (как $enabled_name)"
129 else
130 echo -e "${GREEN}[enabled]${NC} $rel_path"
131 fi
132 done
133 for rel_path in "${disabled_sites[@]}"; do
134 echo -e "${RED}[disabled]${NC} $rel_path"
135 done
136 fi
137 elif [ "$filter" = "enabled" ]; then
138 for rel_path in "${enabled_sites[@]}"; do
139 local enabled_name=$(get_enabled_name "$rel_path")
140 local base_name=$(basename "$rel_path")
141 if [ "$enabled_name" != "$base_name" ]; then
142 echo -e "${GREEN}[enabled]${NC} $rel_path (как $enabled_name)"
143 else
144 echo -e "${GREEN}[enabled]${NC} $rel_path"
145 fi
146 done
147 elif [ "$filter" = "disabled" ]; then
148 for rel_path in "${disabled_sites[@]}"; do
149 echo -e "${RED}[disabled]${NC} $rel_path"
150 done
151 fi
152}
153
154### Включение сайта ###
155enable_site() {
156 local site_path="$1"
157 local link_name="${2:-$(basename "$site_path")}"
158 local available_path="$SITES_AVAILABLE/$site_path"
159 local enabled_path="$SITES_ENABLED/$link_name"
160
161 if [ ! -f "$available_path" ]; then
162 echo -e "${RED}Ошибка: файл $available_path не существует${NC}" >&2
163 exit 1
164 fi
165
166 if is_enabled "$site_path"; then
167 local current_name=$(get_enabled_name "$site_path")
168 if [ "$current_name" != "$(basename "$site_path")" ]; then
169 echo -e "${YELLOW}Предупреждение: сайт уже включен как $current_name${NC}" >&2
170 else
171 echo -e "${YELLOW}Предупреждение: сайт уже включен${NC}" >&2
172 fi
173 return
174 fi
175
176 if sudo ln -s "$available_path" "$enabled_path"; then
177 if [ "$link_name" != "$(basename "$site_path")" ]; then
178 echo -e "${GREEN}Включен: $site_path (как $link_name)${NC}"
179 else
180 echo -e "${GREEN}Включен: $site_path${NC}"
181 fi
182
183 if ! sudo nginx -t; then
184 echo -e "${RED}Ошибка конфигурации!${NC}" >&2
185 rm "$enabled_path"
186 exit 1
187 fi
188
189 sudo systemctl reload nginx
190 echo "NGINX перезагружен"
191 else
192 echo -e "${RED}Ошибка создания симлинка${NC}" >&2
193 exit 1
194 fi
195}
196
197### Выключение сайта ###
198disable_site() {
199 local site_path="$1"
200 local enabled_name=$(get_enabled_name "$site_path")
201 local enabled_path="$SITES_ENABLED/$enabled_name"
202
203 if [ -z "$enabled_name" ]; then
204 echo -e "${YELLOW}Предупреждение: сайт не включен${NC}" >&2
205 return
206 fi
207
208 if sudo rm "$enabled_path"; then
209 if [ "$enabled_name" != "$(basename "$site_path")" ]; then
210 echo -e "${GREEN}Выключен: $enabled_name (ссылался на $site_path)${NC}"
211 else
212 echo -e "${GREEN}Выключен: $site_path${NC}"
213 fi
214
215 if ! sudo nginx -t; then
216 echo -e "${RED}Ошибка конфигурации!${NC}" >&2
217 exit 1
218 fi
219
220 sudo systemctl reload nginx
221 echo "NGINX перезагружен"
222 else
223 echo -e "${RED}Ошибка удаления симлинка${NC}" >&2
224 exit 1
225 fi
226}
227
228### Вывод информации о версии и списка ###
229show_about() {
230 echo ""
231 echo -e "${YELLOW}VHostManage version $VERSION${NC}"
232 echo ""
233 list_sites "all"
234 echo ""
235 echo -e "Use ${YELLOW}vhostmanage help${NC} for help"
236}
237
238
239### Основной код ###
240# check_root
241
242case "$1" in
243 list)
244 list_sites "$2"
245 ;;
246 enable)
247 if [ -z "$2" ]; then
248 echo -e "${RED}Укажите имя сайта${NC}" >&2
249 show_help
250 exit 1
251 fi
252 enable_site "$2" "$3"
253 ;;
254 disable)
255 if [ -z "$2" ]; then
256 echo -e "${RED}Укажите имя сайта${NC}" >&2
257 show_help
258 exit 1
259 fi
260 disable_site "$2"
261 ;;
262 help)
263 show_help
264 ;;
265 "")
266 show_about
267 ;;
268 *)
269 echo -e "${RED}Неизвестная команда: $1${NC}" >&2
270 echo ""
271 show_help
272 exit 1
273 ;;
274esac
275
276