Execute esse script no shell:
cat > /tmp/pve-ctl.sh << 'EOF'
#!/bin/bash
set -u
RED='\033[0;31m'
GRN='\033[0;32m'
YEL='\033[1;33m'
CYN='\033[0;36m'
BLD='\033[1m'
DIM='\033[2m'
NC='\033[0m'
ask() {
local prompt="$1" var="$2"
printf '%b' "$prompt" > /dev/tty
IFS= read -r "$var" < /dev/tty
}
need_bin() {
command -v "$1" >/dev/null 2>&1 || {
echo "Missing $1. Run this on a Proxmox node."
exit 1
}
}
need_bin qm
need_bin pct
confirm() {
local a
ask "${YEL}$1 [y/N]: ${NC}" a
[[ "${a,,}" == "y" || "${a,,}" == "yes" ]]
}
color_status() {
case "${1,,}" in
running) echo -e "${GRN}running${NC}" ;;
stopped) echo -e "${DIM}stopped${NC}" ;;
paused|suspended) echo -e "${YEL}${1}${NC}" ;;
*) echo -e "${CYN}${1}${NC}" ;;
esac
}
build_list() {
GUESTS=()
while IFS= read -r line; do
[[ -z "$line" || "$line" =~ VMID ]] && continue
id=$(awk '{print $1}' <<<"$line")
name=$(awk '{print $2}' <<<"$line")
status=$(awk '{print $3}' <<<"$line")
GUESTS+=("qemu|$id|$name|$status")
done < <(qm list 2>/dev/null)
while IFS= read -r line; do
[[ -z "$line" || "$line" =~ VMID ]] && continue
id=$(awk '{print $1}' <<<"$line")
status=$(awk '{print $2}' <<<"$line")
name=$(awk '{print $NF}' <<<"$line")
GUESTS+=("lxc|$id|$name|$status")
done < <(pct list 2>/dev/null)
}
print_list() {
echo
echo -e "${BLD} # TYPE ID STATUS NAME${NC}"
echo " ------------------------------------------------"
local i=1
for g in "${GUESTS[@]}"; do
IFS='|' read -r typ id name status <<<"$g"
printf " %-3s %-6s %-6s %-22b %s\n" \
"$i" "${typ^^}" "$id" "$(color_status "$status")" "$name"
((i++))
done
echo
}
lookup() {
local sel="$1"
CHOSEN=""
if [[ "$sel" =~ ^[0-9]+$ ]]; then
if (( sel >= 1 && sel <= ${#GUESTS[@]} )); then
CHOSEN="${GUESTS[$((sel-1))]}"
return 0
fi
for g in "${GUESTS[@]}"; do
IFS='|' read -r typ id name status <<<"$g"
if [[ "$id" == "$sel" ]]; then
CHOSEN="$g"
return 0
fi
done
fi
return 1
}
run_action() {
local typ="$1" id="$2" name="$3" action="$4"
local cmd=""
case "$typ:$action" in
qemu:start) cmd="qm start $id" ;;
qemu:shutdown) cmd="qm shutdown $id --timeout 60" ;;
qemu:stop) cmd="qm stop $id" ;;
qemu:reboot) cmd="qm reboot $id --timeout 60" ;;
qemu:reset) cmd="qm reset $id" ;;
lxc:start) cmd="pct start $id" ;;
lxc:shutdown) cmd="pct shutdown $id --timeout 60" ;;
lxc:stop) cmd="pct stop $id" ;;
lxc:reboot) cmd="pct reboot $id --timeout 60" ;;
lxc:reset) cmd="pct stop $id && pct start $id" ;;
*) echo "Unknown action"; return 1 ;;
esac
echo -e "${DIM}→ $cmd${NC}"
eval "$cmd"
local rc=$?
if (( rc == 0 )); then
echo -e "${GRN}OK${NC} ${typ^^} $id ($name)"
else
echo -e "${RED}FAILED${NC} (exit $rc) ${typ^^} $id ($name)"
fi
ask "Press Enter to continue... " _
}
clear
echo -e "${BLD}Proxmox guest control${NC} (this node only)"
echo -e "${DIM}start | shutdown (ACPI) | stop (power cut) | reboot (ACPI) | reset (hard)${NC}"
while true; do
build_list
if ((${#GUESTS[@]} == 0)); then
echo "No VMs or containers found on this node."
exit 0
fi
clear
echo -e "${BLD}Proxmox guest control${NC} (this node only)"
print_list
ask "Guest (# from list or VMID, q=quit): " sel
[[ "${sel,,}" == "q" || "${sel,,}" == "quit" ]] && break
if [[ -z "$sel" ]]; then
continue
fi
if ! lookup "$sel"; then
echo -e "${RED}Not found.${NC} Use the list number or the numeric ID."
ask "Press Enter to continue... " _
continue
fi
IFS='|' read -r typ id name status <<<"$CHOSEN"
echo -e "Selected: ${BLD}${typ^^} $id${NC} $name [$(color_status "$status")]"
echo
echo " 1) start"
echo " 2) shutdown gracefully (ACPI / guest agent)"
echo " 3) stop brutally (instant power-off)"
echo " 4) reboot gracefully (ACPI reboot)"
echo " 5) restart brutally (hard reset)"
echo " b) back"
echo " q) quit"
echo
ask "Action: " act
case "${act,,}" in
1|start|s) action=start ;;
2|shutdown|down|sd) action=shutdown ;;
3|stop|kill|brutal) action=stop ;;
4|reboot|rb) action=reboot ;;
5|reset|restart) action=reset ;;
b|back|"") continue ;;
q|quit) break ;;
*)
echo -e "${RED}Unknown action.${NC}"
ask "Press Enter to continue... " _
continue
;;
esac
if [[ "$action" == "stop" || "$action" == "reset" ]]; then
confirm "This can lose unsaved guest data. Continue?" || continue
fi
if [[ "$action" == "start" && "${status,,}" == "running" ]]; then
echo "Already running."
ask "Press Enter to continue... " _
continue
fi
if [[ "$action" =~ ^(shutdown|stop|reboot|reset)$ && "${status,,}" == "stopped" ]]; then
echo "Already stopped. Start it first."
ask "Press Enter to continue... " _
continue
fi
run_action "$typ" "$id" "$name" "$action"
done
echo "Bye."
EOF
chmod +x /tmp/pve-ctl.sh
clear
/tmp/pve-ctl.shSimples!