Fix bee-boot-status blank screen caused by variable buffering

Command substitution in sh strips trailing newlines, so accumulating
output in a variable via $(...) lost all line breaks. Reverted to
direct printf calls which work correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-05 19:21:10 +03:00
parent a6ac13b5d3
commit 5eb3baddb4

View File

@@ -2,17 +2,11 @@
# bee-boot-status — boot progress display on tty1. # bee-boot-status — boot progress display on tty1.
# Shows live service status until all bee services are done or failed, # Shows live service status until all bee services are done or failed,
# then exits so getty can show the login prompt. # then exits so getty can show the login prompt.
# GUI (lightdm) starts independently without waiting for this.
# Services to wait for before handing off to login prompt.
CRITICAL="bee-preflight bee-nvidia bee-audit" CRITICAL="bee-preflight bee-nvidia bee-audit"
# Services shown with details.
ALL="bee-sshsetup ssh bee-network bee-nvidia bee-preflight bee-audit bee-web" ALL="bee-sshsetup ssh bee-network bee-nvidia bee-preflight bee-audit bee-web"
svc_state() { svc_state() { systemctl is-active "$1.service" 2>/dev/null || echo "inactive"; }
systemctl is-active "$1.service" 2>/dev/null || echo "inactive"
}
svc_icon() { svc_icon() {
case "$(svc_state "$1")" in case "$(svc_state "$1")" in
@@ -26,31 +20,22 @@ svc_icon() {
} }
svc_detail() { svc_detail() {
local svc="$1" local svc="$1" state
local state
state="$(svc_state "$svc")" state="$(svc_state "$svc")"
case "$state" in case "$state" in
failed) failed)
# Show why it failed local res
local msg res="$(systemctl show -p Result "$svc.service" 2>/dev/null | cut -d= -f2)"
msg="$(systemctl show -p Result "$svc.service" 2>/dev/null | cut -d= -f2)" [ -n "$res" ] && [ "$res" != "success" ] && printf ' \033[31m(%s)\033[0m' "$res"
[ -n "$msg" ] && [ "$msg" != "success" ] && printf ' \033[31m(%s)\033[0m' "$msg"
;; ;;
activating) activating)
# Show last journal line
local line local line
line="$(journalctl -u "$svc.service" -n 1 --no-pager --output=cat 2>/dev/null | head -c 60)" line="$(journalctl -u "$svc.service" -n 1 --no-pager --output=cat 2>/dev/null | cut -c1-55)"
[ -n "$line" ] && printf ' \033[90m%s\033[0m' "$line" [ -n "$line" ] && printf ' \033[90m%s\033[0m' "$line"
;; ;;
esac esac
} }
get_ips() {
ip -4 addr show scope global 2>/dev/null \
| awk '/inet /{printf " %s\t%s\n", $NF, $2}'
}
all_critical_done() { all_critical_done() {
for svc in $CRITICAL; do for svc in $CRITICAL; do
case "$(svc_state "$svc")" in case "$(svc_state "$svc")" in
@@ -62,47 +47,43 @@ all_critical_done() {
} }
while true; do while true; do
# Build frame in a variable to reduce flicker # move to top-left and clear screen
out="" printf '\033[H\033[2J'
out="${out}$(printf '\033[H\033[2J')"
out="${out}$(printf '\n')" printf '\n'
out="${out}$(printf ' \033[33m███████╗ █████╗ ███████╗██╗ ██╗ ██████╗ ███████╗███████╗\033[0m\n')" printf ' \033[33m███████╗ █████╗ ███████╗██╗ ██╗ ██████╗ ███████╗███████╗\033[0m\n'
out="${out}$(printf ' \033[33m██╔════╝██╔══██╗██╔════╝╚██╗ ██╔╝ ██╔══██╗██╔════╝██╔════╝\033[0m\n')" printf ' \033[33m██╔════╝██╔══██╗██╔════╝╚██╗ ██╔╝ ██╔══██╗██╔════╝██╔════╝\033[0m\n'
out="${out}$(printf ' \033[33m█████╗ ███████║███████╗ ╚████╔╝ █████╗██████╔╝█████╗ █████╗\033[0m\n')" printf ' \033[33m█████╗ ███████║███████╗ ╚████╔╝ █████╗██████╔╝█████╗ █████╗\033[0m\n'
out="${out}$(printf ' \033[33m██╔══╝ ██╔══██║╚════██║ ╚██╔╝ ╚════╝██╔══██╗██╔══╝ ██╔══╝\033[0m\n')" printf ' \033[33m██╔══╝ ██╔══██║╚════██║ ╚██╔╝ ╚════╝██╔══██╗██╔══╝ ██╔══╝\033[0m\n'
out="${out}$(printf ' \033[33m███████╗██║ ██║███████║ ██║ ██████╔╝███████╗███████╗\033[0m\n')" printf ' \033[33m███████╗██║ ██║███████║ ██║ ██████╔╝███████╗███████╗\033[0m\n'
out="${out}$(printf ' \033[33m╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝\033[0m\n')" printf ' \033[33m╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝\033[0m\n'
out="${out}$(printf ' Hardware Audit LiveCD\n')" printf ' Hardware Audit LiveCD\n'
out="${out}$(printf '\n')" printf '\n'
# Services
for svc in $ALL; do for svc in $ALL; do
out="${out}$(printf ' %s %-20s%s\n' "$(svc_icon "$svc")" "$svc" "$(svc_detail "$svc")")" printf ' %s %-20s%s\n' "$(svc_icon "$svc")" "$svc" "$(svc_detail "$svc")"
done done
out="${out}$(printf '\n')" printf '\n'
# Network # Network
ips="$(get_ips)" ips="$(ip -4 addr show scope global 2>/dev/null | awk '/inet /{printf " %-16s %s\n", $NF, $2}')"
if [ -n "$ips" ]; then if [ -n "$ips" ]; then
out="${out}$(printf ' \033[1mNetwork:\033[0m\n')" printf ' \033[1mNetwork:\033[0m\n'
out="${out}$(printf '%s\n' "$ips")" printf '%s\n' "$ips"
out="${out}$(printf '\n')" printf '\n'
fi fi
# Status line
if all_critical_done; then if all_critical_done; then
out="${out}$(printf ' \033[1mSystem ready.\033[0m Audit is running in the background.\n')" printf ' \033[1;32mSystem ready.\033[0m Audit is running in the background.\n'
if [ -n "$ips" ]; then first_ip="$(ip -4 addr show scope global 2>/dev/null | awk '/inet /{print $2}' | cut -d/ -f1 | head -1)"
first_ip="$(echo "$ips" | awk '{print $2}' | cut -d/ -f1 | head -1)" if [ -n "$first_ip" ]; then
out="${out}$(printf ' Web UI: \033[1mhttp://%s/\033[0m\n' "$first_ip")" printf ' Web UI: \033[1mhttp://%s/\033[0m\n' "$first_ip"
fi fi
printf '%s\n' "$out" printf '\n'
sleep 3 sleep 3
break break
else
out="${out}$(printf ' \033[90mStarting up...\033[0m\n')"
fi fi
printf '%s' "$out" printf ' \033[90mStarting up...\033[0m\n'
sleep 3 sleep 3
done done