feat: suppress systemctl inotify noise, cache service state in menu loop
This commit is contained in:
48
main.sh
48
main.sh
@@ -82,6 +82,19 @@ run_elevated() {
|
|||||||
"$ELEVATE_CMD" "$@"
|
"$ELEVATE_CMD" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# systemctl on some systems logs "Failed to add a watch ... inotify watch limit reached"
|
||||||
|
# to stderr when it talks to PID 1. The operation itself succeeds; suppress the
|
||||||
|
# noisy line so it does not pollute the TUI.
|
||||||
|
run_systemctl() {
|
||||||
|
local line rc
|
||||||
|
while IFS= read -r line; do
|
||||||
|
[[ "$line" == *"Failed to add a watch"*"inotify watch limit reached"* ]] && continue
|
||||||
|
printf '%s\n' "$line"
|
||||||
|
done < <(systemctl "$@" 2>&1) || true
|
||||||
|
rc=${PIPESTATUS[0]}
|
||||||
|
return "$rc"
|
||||||
|
}
|
||||||
|
|
||||||
check_deps() {
|
check_deps() {
|
||||||
local missing=() cmd
|
local missing=() cmd
|
||||||
for cmd in bash curl jq systemctl date stat mktemp sha256sum cmp install dirname basename cut mkdir chmod cp cat printf; do
|
for cmd in bash curl jq systemctl date stat mktemp sha256sum cmp install dirname basename cut mkdir chmod cp cat printf; do
|
||||||
@@ -203,7 +216,7 @@ normalize_service_name() {
|
|||||||
|
|
||||||
validate_service() {
|
validate_service() {
|
||||||
local svc="$1"
|
local svc="$1"
|
||||||
systemctl --no-ask-password cat "$svc" >/dev/null 2>&1
|
run_systemctl --no-ask-password cat "$svc" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure_target_parent() {
|
ensure_target_parent() {
|
||||||
@@ -422,13 +435,13 @@ install_xray_config() {
|
|||||||
restart_xray_service() {
|
restart_xray_service() {
|
||||||
local service="$1"
|
local service="$1"
|
||||||
info "Перезапускаю ${service}…"
|
info "Перезапускаю ${service}…"
|
||||||
if systemctl --no-ask-password restart "$service" 2>/dev/null; then
|
if run_systemctl --no-ask-password restart "$service" 2>/dev/null; then
|
||||||
ok "Служба ${service} перезапущена."
|
ok "Служба ${service} перезапущена."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
elevate_available || die "Не удалось перезапустить ${service}: нет прав и не найден doas/run0/pkexec/sudo."
|
elevate_available || die "Не удалось перезапустить ${service}: нет прав и не найден doas/run0/pkexec/sudo."
|
||||||
run_elevated systemctl --no-ask-password restart "$service"
|
run_elevated run_systemctl --no-ask-password restart "$service"
|
||||||
ok "Служба ${service} перезапущена."
|
ok "Служба ${service} перезапущена."
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -540,12 +553,12 @@ xray_socks_endpoint() {
|
|||||||
|
|
||||||
service_state_raw() {
|
service_state_raw() {
|
||||||
local service="$1"
|
local service="$1"
|
||||||
systemctl --no-ask-password is-active "$service" 2>/dev/null || true
|
run_systemctl --no-ask-password is-active "$service" 2>/dev/null || true
|
||||||
}
|
}
|
||||||
|
|
||||||
service_enabled_raw() {
|
service_enabled_raw() {
|
||||||
local service="$1"
|
local service="$1"
|
||||||
systemctl --no-ask-password is-enabled "$service" 2>/dev/null || true
|
run_systemctl --no-ask-password is-enabled "$service" 2>/dev/null || true
|
||||||
}
|
}
|
||||||
|
|
||||||
service_state_colored() {
|
service_state_colored() {
|
||||||
@@ -582,7 +595,7 @@ run_service_action() {
|
|||||||
say ""
|
say ""
|
||||||
info "systemctl ${action} ${service}"
|
info "systemctl ${action} ${service}"
|
||||||
|
|
||||||
if systemctl --no-ask-password "$action" "$service" 2>/dev/null; then
|
if run_systemctl --no-ask-password "$action" "$service" 2>/dev/null; then
|
||||||
ok "Готово: ${service} → ${action}."
|
ok "Готово: ${service} → ${action}."
|
||||||
pause_screen
|
pause_screen
|
||||||
hide_cursor
|
hide_cursor
|
||||||
@@ -596,7 +609,7 @@ run_service_action() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if run_elevated systemctl --no-ask-password "$action" "$service"; then
|
if run_elevated run_systemctl --no-ask-password "$action" "$service"; then
|
||||||
ok "Готово: ${service} → ${action}."
|
ok "Готово: ${service} → ${action}."
|
||||||
else
|
else
|
||||||
warn "systemctl ${action} завершился с ошибкой. Проверьте статус службы."
|
warn "systemctl ${action} завершился с ошибкой. Проверьте статус службы."
|
||||||
@@ -612,7 +625,7 @@ show_service_status_screen() {
|
|||||||
clear_screen
|
clear_screen
|
||||||
say "${C_BOLD}${C_MAGENTA}✦ Статус службы ${service}${C_RESET}"
|
say "${C_BOLD}${C_MAGENTA}✦ Статус службы ${service}${C_RESET}"
|
||||||
say ""
|
say ""
|
||||||
if ! systemctl --no-ask-password --no-pager --full status "$service" -n 18; then
|
if ! run_systemctl --no-ask-password --no-pager --full status "$service" -n 18; then
|
||||||
warn "Не удалось прочитать статус через systemctl."
|
warn "Не удалось прочитать статус через systemctl."
|
||||||
fi
|
fi
|
||||||
pause_screen
|
pause_screen
|
||||||
@@ -663,6 +676,7 @@ render_profile_row() {
|
|||||||
render_menu() {
|
render_menu() {
|
||||||
local cursor="$1" count saved_index i cache_info selected_name
|
local cursor="$1" count saved_index i cache_info selected_name
|
||||||
local service service_state service_enabled xray_config socks_endpoint
|
local service service_state service_enabled xray_config socks_endpoint
|
||||||
|
local now
|
||||||
|
|
||||||
count="$(profile_count)"
|
count="$(profile_count)"
|
||||||
saved_index="$(cfg_get selected_index)"
|
saved_index="$(cfg_get selected_index)"
|
||||||
@@ -671,8 +685,17 @@ render_menu() {
|
|||||||
xray_config="$(cfg_get xray_config)"
|
xray_config="$(cfg_get xray_config)"
|
||||||
socks_endpoint="$(xray_socks_endpoint "$xray_config")"
|
socks_endpoint="$(xray_socks_endpoint "$xray_config")"
|
||||||
cache_info="$(subscription_update_info)"
|
cache_info="$(subscription_update_info)"
|
||||||
service_state="$(service_state_raw "$service")"
|
|
||||||
service_enabled="$(service_enabled_raw "$service")"
|
# Polling systemd on every keypress can exhaust inotify watches quickly.
|
||||||
|
# Cache the state for a short interval inside the menu loop.
|
||||||
|
now="$(date +%s)"
|
||||||
|
if [[ -z "${_MENU_STATE_CACHE_TS:-}" || $(( now - _MENU_STATE_CACHE_TS )) -gt 2 ]]; then
|
||||||
|
_MENU_STATE_CACHE_TS="$now"
|
||||||
|
_MENU_STATE_CACHE_VALUE="$(service_state_raw "$service")"
|
||||||
|
_MENU_ENABLED_CACHE_VALUE="$(service_enabled_raw "$service")"
|
||||||
|
fi
|
||||||
|
service_state="${_MENU_STATE_CACHE_VALUE}"
|
||||||
|
service_enabled="${_MENU_ENABLED_CACHE_VALUE}"
|
||||||
|
|
||||||
clear_screen
|
clear_screen
|
||||||
say "${C_BOLD}${C_MAGENTA}✦ Xray JSON TUI${C_RESET}"
|
say "${C_BOLD}${C_MAGENTA}✦ Xray JSON TUI${C_RESET}"
|
||||||
@@ -751,15 +774,19 @@ menu() {
|
|||||||
;;
|
;;
|
||||||
s|S)
|
s|S)
|
||||||
run_service_action start "$service"
|
run_service_action start "$service"
|
||||||
|
unset _MENU_STATE_CACHE_TS _MENU_STATE_CACHE_VALUE _MENU_ENABLED_CACHE_VALUE
|
||||||
;;
|
;;
|
||||||
o|O)
|
o|O)
|
||||||
run_service_action stop "$service"
|
run_service_action stop "$service"
|
||||||
|
unset _MENU_STATE_CACHE_TS _MENU_STATE_CACHE_VALUE _MENU_ENABLED_CACHE_VALUE
|
||||||
;;
|
;;
|
||||||
e|E)
|
e|E)
|
||||||
run_service_action restart "$service"
|
run_service_action restart "$service"
|
||||||
|
unset _MENU_STATE_CACHE_TS _MENU_STATE_CACHE_VALUE _MENU_ENABLED_CACHE_VALUE
|
||||||
;;
|
;;
|
||||||
v|V)
|
v|V)
|
||||||
show_service_status_screen "$service"
|
show_service_status_screen "$service"
|
||||||
|
unset _MENU_STATE_CACHE_TS _MENU_STATE_CACHE_VALUE _MENU_ENABLED_CACHE_VALUE
|
||||||
;;
|
;;
|
||||||
q|Q)
|
q|Q)
|
||||||
clear_screen
|
clear_screen
|
||||||
@@ -770,6 +797,7 @@ menu() {
|
|||||||
show_cursor
|
show_cursor
|
||||||
say ""
|
say ""
|
||||||
apply_selection "$cursor"
|
apply_selection "$cursor"
|
||||||
|
unset _MENU_STATE_CACHE_TS _MENU_STATE_CACHE_VALUE _MENU_ENABLED_CACHE_VALUE
|
||||||
pause_screen
|
pause_screen
|
||||||
hide_cursor
|
hide_cursor
|
||||||
;;
|
;;
|
||||||
|
|||||||
Reference in New Issue
Block a user