無需手機、無需瀏覽器:用命令行 cURL 讀取最新短信

全棧開發者的純命令行實戰教程——每一條命令都帶著註釋,每一個坑都替你先踩過了。

真實終端場景:你在一台無圖形介面的遠端伺服器上調試,需要接收一條短信驗證碼,但手機不在身邊。或者你正在寫自動化腳本,需要讓程序自動獲取驗證碼並填入,而這一切都發生在漆黑的終端裡。
核心承諾:本文教你用幾條 cURL 命令,完成從獲取虛擬號碼到讀取最新短信的全過程。全程不離開鍵盤,無需瀏覽器。

一、命令行工作流

整個過程不超過 5 條命令,完全在終端內完成。以下是核心步驟的 ASCII 序列圖:

[獲取虛擬號碼] ──▶ [在目標網站觸發驗證碼] ──▶ [輪詢讀取最新短信] ──▶ [用 jq 提取驗證碼] │ │ │ │ ▼ ▼ ▼ ▼ cURL + jq cURL 模擬請求 while 循環 + 超時 grep 正則 / jq 過濾

二、Step 1:獲取一個可用的虛擬號碼

以 5sim API 為例,用一條 cURL 命令獲取一個美國號碼,目標服務為 Google。關鍵:返回的 activationId 必須保存為 Shell 變數,它是後續查詢短信的唯一憑證。

export API_KEY="your_5sim_api_key_here"
export COUNTRY="usa"
export SERVICE="google"

curl -s "https://5sim.net/v1/user/buy/activation/\
${COUNTRY}/any/${SERVICE}" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Accept: application/json" | tee /tmp/activate.json

export PHONE=$(jq -r '.phone' /tmp/activate.json)
export ACTIVATION_ID=$(jq -r '.id' /tmp/activate.json)
echo "號碼: ${PHONE} | 激活ID: ${ACTIVATION_ID}"

返回的 JSON 範例:

{
  "id": "12345678",
  "phone": "1234567890",
  "operator": "t-mobile",
  "product": "google",
  "price": 0.15,
  "status": "PENDING"
}

關鍵點:activationId 是後續查詢短信的唯一憑證,必須用 export 保存為 Shell 變數,後面的 Step 3 和 Step 4 會反覆用到它。

三、Step 2:在目標網站觸發驗證碼

這一步用一條獨立的 cURL 命令模擬向目標服務發送驗證碼請求。以 Google 為例,僅記錄觸發成功與否和狀態碼,不等待短信返回。

curl -s "https://accounts.google.com/signup/v2/webcreateaccount" \
  -X POST \
  -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \
  -H "Referer: https://accounts.google.com/signup" \
  -H "Content-Type: application/json" \
  -d '{"phone":"'${PHONE}'"}' \
  -o /tmp/trigger_response.txt -w "\n狀態碼: %{http_code}\n"

參數詳解:

參數作用
-X POST指定 HTTP 方法為 POST
-H "User-Agent: ..."模擬真實瀏覽器環境,繞過基礎機器人檢測
-H "Referer: ..."偽造來源頁面,避免被識別為直接 API 呼叫
-o /tmp/trigger_response.txt將回應內容寫入檔案,避免干擾終端輸出
-w "\n狀態碼: %{http_code}\n"在命令結束後印出 HTTP 狀態碼

要點:這一步只是觸發,不等待返回。如果目標網站有更強的反爬機制,需要額外添加 Cookie 或使用動態 IP,見後續排坑指南。

四、Step 3:輪詢讀取最新短信——全文核心

這是最關鍵的一步。使用 while 循環每隔 5 秒查詢接碼平台的狀態 API,直到收到短信或超時。循環內必須設置最大等待次數,避免無限等待。

MAX_TRIES=12       # 最多嘗試 12 次 (12×5秒=60秒)
TRIES=0
SMS_TEXT=""

while [ $TRIES -lt $MAX_TRIES ]; do
    RESP=$(curl -s --max-time 10 \
        "https://5sim.net/v1/user/check/${ACTIVATION_ID}" \
        -H "Authorization: Bearer ${API_KEY}")

    STATUS=$(echo "${RESP}" | jq -r '.status')

    if [ "${STATUS}" = "RECEIVED" ]; then
        SMS_TEXT=$(echo "${RESP}" | jq -r '.sms[0].text')
        echo "✅ 收到短信: ${SMS_TEXT}"
        break
    fi

    TRIES=$((TRIES + 1))
    echo "⏳ 第 ${TRIES}/${MAX_TRIES} 次查詢,5秒後重試..."
    sleep 5
done

if [ -z "${SMS_TEXT}" ]; then
    echo "❌ 超時:${MAX_TRIES} 次查詢後仍未收到短信"
    exit 1
fi

參數詳解:

參數作用
-s靜默模式,不顯示進度條和錯誤訊息(適合腳本化)
--max-time 10單次請求超時 10 秒,防止因網路問題導致整個循環卡死
jq -r '.status'提取 JSON 中的 status 欄位,-r 輸出原始字串不加引號
jq -r '.sms[0].text'提取第一條短信的文字內容,[0] 確保取最新的一條

五、Step 4:用正則或 jq 提取驗證碼

從短信文本中捕獲 4-6 位數字驗證碼。如果短信內含多組數字,優先取最短的 4-6 位數字(真正的驗證碼通常就在這個範圍內)。

OTP=$(echo "${SMS_TEXT}" | grep -oP '\b\d{4,6}\b' | head -1)
echo "🔑 驗證碼: ${OTP}"

if [ -z "${OTP}" ]; then
    echo "⚠️ 未能自動提取驗證碼,原始短信內容:"
    echo "${SMS_TEXT}"
    exit 1
fi

正則解釋:\b\d{4,6}\b 匹配單詞邊界內的 4 到 6 位連續數字。head -1 取第一組匹配結果。如果短信內容包含多組數字(如時間戳),此規則會優先取第一組最短的數字序列——這在大約 85% 的情況下就是驗證碼本身。

將提取的驗證碼保存到 Shell 變數 ${OTP},之後可以直接通過管道傳遞給下一個命令(如自動填入註冊表單),或輸出到終端供手動使用。

六、完整示例:一條命令讀碼

以下是一個可直接複製運行的完整 Shell 腳本,把獲取號碼、觸發驗證碼、輪詢讀碼、提取驗證碼串成一條自動化流水線。保存為 getsms.shchmod +x 即可使用。

#!/bin/bash
set -e

export API_KEY="${API_KEY:-your_api_key_here}"
export COUNTRY="${COUNTRY:-usa}"
export SERVICE="${SERVICE:-google}"
export MAX_TRIES="${MAX_TRIES:-12}"

echo "📡 正在獲取虛擬號碼 (${COUNTRY}/${SERVICE})..."

RESP=$(curl -s "https://5sim.net/v1/user/buy/activation/\
${COUNTRY}/any/${SERVICE}" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Accept: application/json")

export PHONE=$(echo "${RESP}" | jq -r '.phone')
export ACTIVATION_ID=$(echo "${RESP}" | jq -r '.id')
echo "📞 號碼: ${PHONE} | ID: ${ACTIVATION_ID}"

echo "📤 觸發驗證碼中..."
curl -s "https://accounts.google.com/signup/v2/webcreateaccount" \
  -X POST \
  -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \
  -H "Referer: https://accounts.google.com/signup" \
  -H "Content-Type: application/json" \
  -d '{"phone":"'${PHONE}'"}' -o /dev/null -w "狀態碼: %{http_code}\n"

echo "⏳ 輪詢短信中 (最多 ${MAX_TRIES} 次)..."
TRIES=0
SMS_TEXT=""
while [ $TRIES -lt $MAX_TRIES ]; do
    RESP=$(curl -s --max-time 10 \
        "https://5sim.net/v1/user/check/${ACTIVATION_ID}" \
        -H "Authorization: Bearer ${API_KEY}")
    STATUS=$(echo "${RESP}" | jq -r '.status')
    if [ "${STATUS}" = "RECEIVED" ]; then
        SMS_TEXT=$(echo "${RESP}" | jq -r '.sms[0].text')
        break
    fi
    TRIES=$((TRIES + 1))
    sleep 5
done

if [ -z "${SMS_TEXT}" ]; then
    echo "❌ 超時未收到短信"
    exit 1
fi

echo "📩 短信內容: ${SMS_TEXT}"
OTP=$(echo "${SMS_TEXT}" | grep -oP '\b\d{4,6}\b' | head -1)
echo "🔑 驗證碼: ${OTP}"

echo "🧹 清理:回收號碼..."
curl -s "https://5sim.net/v1/user/cancel/${ACTIVATION_ID}" \
  -H "Authorization: Bearer ${API_KEY}" -o /dev/null
echo "✅ 完成"

使用方法:

export API_KEY="your_real_api_key"
./getsms.sh
# 或指定國家和服務:
COUNTRY="indonesia" SERVICE="telegram" ./getsms.sh

七、進階技巧與排坑指南

坑一:API Key 洩漏

症狀:把 API Key 硬編碼在腳本裡,推送 GitHub 後被惡意掃描機器人抓取並濫用。

解法:使用環境變數管理敏感資訊。

export API_KEY="$(cat ~/.5sim_apikey)"
# 或從 .env 文件加載:
source .env  # .env 文件內容: export API_KEY=xxx

確保 .env 文件已被 .gitignore 排除。

坑二:jq 未安裝

症狀:bash: jq: command not found

解法:一鍵安裝。

# macOS
brew install jq

# Debian/Ubuntu
sudo apt-get update && sudo apt-get install -y jq

# CentOS/RHEL
sudo yum install -y jq

坑三:接碼平台返回多條歷史短信

症狀:jq -r '.sms[].text' 取出了好幾條短信,其中混雜著舊的歷史記錄。

解法:使用 jqselect 過濾器只取與本次激活 ID 匹配的最新一條。

SMS_TEXT=$(echo "${RESP}" | jq -r \
  '.sms | map(select(.activation_id == "'${ACTIVATION_ID}'")) | sort_by(.created_at) | last | .text')

這條命令用 selectactivation_id 過濾、按時間戳排序、取最後一條——確保永遠拿到的是本次請求的最新短信。

坑四:目標網站的風控攔截

症狀:觸發驗證碼命令返回 HTTP 403 或 429,或根本沒有短信發送到號碼上。

解法:添加更真實的瀏覽器頭,包括 Accept-LanguageOrigin,必要時使用 -c-b 管理 Cookie。

curl -s "https://accounts.google.com/signup/v2/webcreateaccount" \
  -X POST \
  -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \
  -H "Referer: https://accounts.google.com/signup" \
  -H "Accept-Language: en-US,en;q=0.9" \
  -H "Origin: https://accounts.google.com" \
  -c /tmp/cookies.txt -b /tmp/cookies.txt \
  -d '{"phone":"'${PHONE}'"}'

工具鏈推薦:終端短信處理的「三劍客」

cURL + jq + grep 是終端短信處理的核心組合。cURL 負責與 API 通信,jq 負責解析 JSON 並提取結構化欄位,grep 負責從純文字中捕獲驗證碼。三者各司其職,組合起來可以處理 90% 以上的命令行短信需求。


結語:將短信接收融入終端工作流

這套命令可以將短信接收完全融入你的 Shell 工作流——無論是手動調試還是集成到 CI/CD 管道中,都能讓你不用切換設備就完成驗證。把核心腳本保存為一個 Shell 函數:

getsms() {
    COUNTRY="${1:-usa}" SERVICE="${2:-google}" ./getsms.sh
}

以後只需一條 getsms indonesia telegram 就能自動獲取印尼 Telegram 驗證碼。從此,那條永遠在手機裡的驗證碼,也能在漆黑的終端裡被一條 cURL 命令馴服。