用 bash 变量替换 curl 命令中的 IP

Replacing IP in curl command with bash variable

我目前正在尝试制作一个与 Cloudflare API 交互的 DDNS 脚本,以捕获我的 IP 地址变化并自动修复我的网络服务器的 IP 地址变化。到目前为止一切正常,除了我无法将 $IP 正确放入 curl 语句中。我首先从 bash 脚本中 运行 一个 python 脚本来获取 ip 地址,然后 运行 bash 脚本中的 curl 语句。这是 python 脚本的样子(它 return 是一个 IP 地址,如“1.1.1.1”,包含引号,因为 curl 命令需要引号)

#!/usr/bin/python3

import subprocess as sp

def main():
    command = "dig +short myip.opendns.com @resolver1.opendns.com";
    ip = sp.check_output(command, shell=True).decode('utf-8').strip('\n');
    ip_tmp = ip;
    ip_tmp = '"' + ip + '"';
    ip = ip_tmp;
    print(ip);


if __name__ == "__main__":
    main();

bash 脚本如下所示:

#!/bin/bash

IP=$("./getIP.py")

curl -X PUT "https://api.cloudflare.com/client/v4/zones/zone_id/dns_records/dns_id" \
     -H "X-Auth-Email: example.com" \
     -H "X-Auth-Key: authkey" \
     -H "Content-Type: application/json" \
     --data '{"type":"A","name":"example.com","content":$IP,"ttl":120,"proxied":true}'

我试过 python 脚本只有 return 数字,然后在 bash 脚本中添加引号,现在反之亦然,我似乎无法得到它工作。一旦变量替换为 ip 地址周围的引号,最后一行应该看起来像这样:

'{"type":"A","name":"example.com","content":"127.0.0.1","ttl":120,"proxied":true}'

json 结构两边的单引号阻止变量扩展。

您有一些现成的选项。

转义 inside/around 你的 json.

的丑陋引用
"{\"type\":\"A\",\"name\":\"example.com\",\"content\":$IP,\"ttl\":120,\"proxied\":true}"

让 python 将此数据写入文件并告诉 curl 使用该文件作为 post 数据的来源。

curl -X PUT "https://api.cloudflare.com/client/v4/zones/zone_id/dns_records/dns_id" \
 -H "X-Auth-Email: example.com" \
 -H "X-Auth-Key: authkey" \
 -H "Content-Type: application/json" \
 --data @file_you_wrote_your_json_to.json

使用 python 请求或 urllib 模块向 cloud flare 发出请求。

将您的 main() 函数更新为 return IP 而不是打印它。

my_ip = main()
url = "https://api.cloudflare.com/client/v4/zones/zone_id/dns_records/dns_id"

myheaders = {
    "X-Auth-Email": "example.com",
    "X-Auth-Key": "authkey",
    "Content-Type": "application/json"
}

myjson = {
    "type":"A",
    "name":"example.com",
    "content":my_ip,
    "ttl":120,
    "proxied":true
}

requests.put(url, headers=myheaders, data=myjson)

更好的是,只需在 bash 中完成即可。 Cloudflare DDNS on github.

一次获取动态A-record ID:

curl -X GET "https://api.cloudflare.com/client/v4/zones/**Zone ID** \
                    /dns_records?type=A&name=dynamic" \
     -H "Host: api.cloudflare.com" \
     -H "User-Agent: ddclient/3.9.0" \
     -H "Connection: close" \
     -H "X-Auth-Email: example@example.com" \
     -H "X-Auth-Key: "**Authorization key**" \
     -H "Content-Type: application/json"

Cron 作业 (* * * * *) 设置动态 A-record:

#/usr/bin/env sh

AUTH_EMAIL=example@example.com
AUTH_KEY=** CF Authorization  key **
ZONE_ID=** CF Zone ID **
A_RECORD_NAME="dynamic"
A_RECORD_ID=** CF A-record ID from cloudflare-dns-id.sh **

IP_RECORD="/tmp/ip-record"
RECORDED_IP=`cat $IP_RECORD`
PUBLIC_IP=$(curl --silent https://api.ipify.org) || exit 1

if [ "$PUBLIC_IP" = "$RECORDED_IP" ]; then
    exit 0
fi

echo $PUBLIC_IP > $IP_RECORD

RECORD=$(cat <<EOF
{ "type": "A",
  "name": "$A_RECORD_NAME",
  "content": "$PUBLIC_IP",
  "ttl": 180,
  "proxied": false }
EOF
)
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID \
             /dns_records/$A_RECORD_ID" \
     -X PUT \
     -H "Content-Type: application/json" \
     -H "X-Auth-Email: $AUTH_EMAIL" \
     -H "X-Auth-Key: $AUTH_KEY" \
     -d "$RECORD"