2016-05-27 2 views
2

Цель:Как использовать переменную в запросе CURL с bash?

Я использую CURL Баш скрипт для подключения к Cloudflare APIv4. Цель состоит в том, чтобы обновить A-запись. Мой сценарий:

# Get current public IP 
     current_ip=curl --silent ipecho.net/plain; echo 

    # Update A record 
     curl -X PUT "https://api.cloudflare.com/client/v4/zones/ZONEIDHERE/dns_records/DNSRECORDHERE" \ 
     -H "X-Auth-Email: EMAILHERE" \ 
     -H "X-Auth-Key: AUTHKEYHERE" \ 
     -H "Content-Type: application/json" \ 
     --data '{"id":"ZONEIDHERE","type":"A","name":"example.com","content":"'"${current_ip}"'","zone_name":"example.com"}' 

Проблема:

Переменная current_ip не печатается, когда я называю это в моем сценарии. Выход будет "content" : "", а не "content" : "1.2.3.4".

Я использовал other stackoverflow posts, и я пытаюсь следовать их примерам, но я думаю, что я все еще делаю что-то неправильно, просто не могу понять, что. :(

ответ

5

Использование jq для этого, как предполагает ответ Чарльза Даффи, это очень хорошая идея, однако, если вы можете. т или не хотите установить JQ здесь то, что вы можете сделать с обычной POSIX оболочки.

#!/bin/sh 
set -e 

current_ip="$(curl --silent --show-error --fail ipecho.net/plain)" 
echo "IP: $current_ip" 

# Update A record 
curl -X PUT "https://api.cloudflare.com/client/v4/zones/ZONEIDHERE/dns_records/DNSRECORDHERE" \ 
    -H "X-Auth-Email: EMAILHERE" \ 
    -H "X-Auth-Key: AUTHKEYHERE" \ 
    -H "Content-Type: application/json" \ 
    --data @- <<END; 
{ 
    "id": "ZONEIDHERE", 
    "type": "A", 
    "name": "example.com", 
    "content": "$current_ip", 
    "zone_name": "example.com" 
} 
END 
+0

Основное место, где это падает, - это если у вас есть контент, который нельзя буквально заменить в документе JSON без необходимости кавычек или экранирования, но это вряд ли произойдет для IP-адреса, поэтому это разумное место немного скомпрометировать. –

+0

... Я мог бы поставить '|| exit' в конце задания из результатов 'curl', так что мы не будем продолжать работу в случае сбоя или' [[$ current_ip]] || exit' (или, скорее, поскольку вы используете '#!/bin/sh',' [-n "$ current_ip"] || exit') на следующей строке; '--fail' гарантирует, что статус выхода curl отражает сбой, но если оболочка не была запущена с' -e', это не обязательно будет вести себя в соответствии с этим статусом выхода. –

+1

Да, точно. Вы должны быть очень осторожны при манипулировании JSON как текстом и избегать его, если это возможно. Даже если ваша машина * nix не имеет jq, она, вероятно, имеет Perl или Python. Если вы сомневаетесь, используйте один из них, чтобы подготовить JSON. – nwk

3

Надежный способ редактирования JSON из сценариев оболочки является использование jq:

# set shell variables with your contents 
email="yourEmail" 
authKey="yourAuthKey" 
zoneid="yourZoneId" 
dnsrecord="yourDnsRecord" 

# make sure we show errors; --silent without --show-error can mask problems. 
current_ip=$(curl --fail -sS ipecho.net/plain) || exit 

# optional: template w/ JSON content that won't change 
json_template='{"type": "A", "name": "example.com"}' 

# build JSON with content that *can* change with jq 
json_data=$(jq --arg zoneid="$zoneid" \ 
       --arg current_ip="$current_ip" \ 
       '.id=$zoneid | .content=$current_ip' \ 
       <<<"$json_template") 

# ...and submit 
curl -X PUT "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records/$dnsrecord" \ 
    -H "X-Auth-Email: $email" \ 
    -H "X-Auth-Key: $authKey" \ 
    -H "Content-Type: application/json" \ 
    --data "$json_data" 
+0

Я думаю, что с помощью JQ является прекрасным решением проблемы! код также очень чистый и прямо вперед, спасибо за код! Тем не менее, я хочу попытаться использовать простой b пепел без надстроек и даже (если возможно) без использования python или perl. Я не упоминал об этом в своем сообщении, поэтому я все еще ищу вариант без jq, прежде чем принимать это как ответ. +1 для решения –