Heart分享
一个用于查找比您现有服务器更便宜的 Hetzner 服务器的脚本
440
猫猫超管
2025/11/12·发布 2025/11/12
Shell
1#!/bin/bash
2#
3# Hetzner Cloud Server Info & Cost Optimizer
4#
5# Description:
6#   Fetches all servers from your Hetzner Cloud account and analyzes their pricing.
7#   For each server, it identifies cheaper server types with equal or better specs.
8#   Results are exported to a tab-separated file (servers.txt) with cost savings.
9#
10# Setup:
11#   1. Create a .env file in the same directory with your Hetzner API token:
12#      HETZNER_API_TOKEN=your_token_here
13#   2. Ensure jq and curl are installed
14#   3. Make the script executable: chmod +x get_server_info.sh
15#
16# Usage:
17#   ./get_server_info.sh
18#
19#   Output file (servers.txt) contains columns:
20#   - Server name, type, IP, cores, RAM, disk, current price
21#   - Cheaper alternative type, price, and potential savings (if available)
22#
23
24if [ -f ".env" ]; then
25    source .env
26else
27    echo "Error: .env file not found"
28    exit 1
29fi
30
31if [ -z "$HETZNER_API_TOKEN" ]; then
32    echo "Error: HETZNER_API_TOKEN not set in .env file"
33    exit 1
34fi
35
36OUTPUT_FILE="servers.txt"
37
38> "$OUTPUT_FILE"
39
40echo "Fetching servers from Hetzner Cloud API..."
41
42echo "Fetching available server types..."
43server_types_response=$(curl -s -H "Authorization: Bearer $HETZNER_API_TOKEN" "https://api.hetzner.cloud/v1/server_types")
44
45all_servers=""
46
47for page in 1 2 3; do # very basic pagination, adjust as needed
48    echo "Fetching servers page $page..."
49    api_response=$(curl -s -H "Authorization: Bearer $HETZNER_API_TOKEN" "https://api.hetzner.cloud/v1/servers?page=$page&per_page=50")
50    
51    if [ $? -ne 0 ]; then
52        echo "Error: Failed to fetch servers from Hetzner API (page $page)"
53        exit 1
54    fi
55    
56    if [ -z "$all_servers" ]; then
57        all_servers="$api_response"
58    else
59        all_servers=$(echo "$all_servers" | jq --argjson new "$api_response" '.servers += $new.servers')
60    fi
61done
62
63echo "$all_servers" | jq -r '.servers[] | 
64    [
65        .name,
66        .server_type.name,
67        .public_net.ipv4.ip,
68        (.server_type.cores | tostring),
69        (.server_type.memory | tostring),
70        (.server_type.disk | tostring),
71        (.server_type.prices[0].price_monthly.gross)
72    ] | @tsv' | while IFS=$'\t' read -r name server_type ip cores ram_gb disk price; do
73    
74    disk_gb="$disk"
75    
76    price_formatted=$(printf "%.2f" "$price" | sed 's/\./,/')
77    
78    cheaper_option=$(echo "$server_types_response" | jq -r --arg cores "$cores" --arg ram "$ram_gb" --arg disk "$disk" --arg current_price "$price" '
79        [.server_types[] | 
80        select(
81            (.cores >= ($cores | tonumber)) and 
82            (.memory >= ($ram | tonumber)) and 
83            (.disk >= ($disk | tonumber)) and
84            (.prices[0].price_monthly.gross | tonumber) < ($current_price | tonumber)
85        ) | 
86        {name: .name, price: (.prices[0].price_monthly.gross | tonumber)}] |
87        sort_by(.price) | 
88        .[0] // empty |
89        [.name, (.price | tostring)] | 
90        @tsv
91    ')
92    
93    if [ -n "$cheaper_option" ]; then
94        cheaper_type=$(echo "$cheaper_option" | cut -f1)
95        cheaper_price=$(echo "$cheaper_option" | cut -f2)
96        cheaper_price_formatted=$(printf "%.2f" "$cheaper_price" | sed 's/\./,/')
97        savings=$(echo "$price - $cheaper_price" | bc)
98        savings_formatted=$(printf "%.2f" "$savings" | sed 's/\./,/')
99        
100        echo "Processing: $name ($server_type) - Cheaper option available: $cheaper_type"
101        printf "%s\t%s\t%s\t%s\t%sGB\t%sGB\t%s\t%s\t%s\t%s\n" "$name" "$server_type" "$ip" "$cores" "$ram_gb" "$disk_gb" "$price_formatted" "$cheaper_type" "$cheaper_price_formatted" "$savings_formatted" >> "$OUTPUT_FILE"
102    else
103        echo "Processing: $name ($server_type) - Best price"
104        printf "%s\t%s\t%s\t%s\t%sGB\t%sGB\t%s\t-\t-\t-\n" "$name" "$server_type" "$ip" "$cores" "$ram_gb" "$disk_gb" "$price_formatted" >> "$OUTPUT_FILE"
105    fi
106done
107
108echo ""
109echo "Done! Results written to $OUTPUT_FILE"
Gist 8ba56504...
gist.statsUnavailable

最后更新 11月12日 10:03
Hetzner

评论 (0)

还没有评论,来说点什么吧~