Script to add/update Cloudflare DDNS records failed. API v4, multiple A records

I’m trying to use Cloudflare API v4 to set up DDNS on my server. I need to update multiple DNS records in one script file, but I’m new to scripting with .sh files.

I’ve found a script online (script1.sh) that works for a single DNS record update, but not for multiple records (script2.sh):

NEW_IP=`curl -s http://ipv4.icanhazip.com`
CURRENT_IP=`cat /Users/foo/Desktop/cloudflare/current_ip.txt`

if [ "$NEW_IP" = "$CURRENT_IP" ]
then
        echo "No Change in IP Adddress"
else
curl -X PUT "https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{dns_record_id}" \
     -H "X-Auth-Email: {my_email}" \
     -H "X-Auth-Key: {global_api_key}" \
     -H "Content-Type: application/json" \
     --data '{"type":"A","name":"{domain_name}","content":"'$NEW_IP'","ttl":1,"proxied":true}' 
echo $NEW_IP > /Users/foo/Desktop/cloudflare/current_ip.txt
fi
NEW_IP=`curl -s http://ipv4.icanhazip.com`
CURRENT_IP=`cat /Users/foo/Desktop/cloudflare/current_ip.txt`

if [ "$NEW_IP" = "$CURRENT_IP" ]
then
        echo "No Change in IP Adddress"
else
#domain-one
curl -X PUT "https://api.cloudflare.com/client/v4/zones/{zone_id_for_domain_one}/dns_records/{dns_record_id_for_domain_one_record_one}" \
     -H "X-Auth-Email: {my_email}" \
     -H "X-Auth-Key: {global_api_key}" \
     -H "Content-Type: application/json" \
     --data '{"type":"A","name":"domain-one.com","content":"'$NEW_IP'","ttl":1,"proxied":true}'
curl -X PUT "https://api.cloudflare.com/client/v4/zones/{zone_id_for_domain_one}/dns_records/{dns_record_id_for_domain_one_record_two}" \
     -H "X-Auth-Email: {my_email}" \
     -H "X-Auth-Key: {global_api_key}" \
     -H "Content-Type: application/json" \
     --data '{"type":"A","name":"subdomain.domain-one.com","content":"'$NEW_IP'","ttl":1,"proxied":true}'
#domain-two
curl -X PUT "https://api.cloudflare.com/client/v4/zones/{zone_id_for_domain_two}/dns_records/{dns_record_id_for_domain_two_record}" \
     -H "X-Auth-Email: {my_email}" \
     -H "X-Auth-Key: {global_api_key}" \
     -H "Content-Type: application/json" \
     --data '{"type":"A","name":"domain-two.com","content":"'$NEW_IP'","ttl":1,"proxied":true}'
echo $NEW_IP > /Users/foo/Desktop/cloudflare/current_ip.txt
fi

When manually running the scripts with sh /Users/foo/Desktop/script-name.sh, script1.sh works but script2.sh returns an error -bash: fork: Resource temporarily unavailable. When running the scripts with cron, the same error occurs.

Can you help me figure out what’s wrong with the script?

The error -bash: fork: Resource temporarily unavailable occurs when the script attempts to spawn too many child processes, exceeding the system’s limit. This can happen when running multiple curl commands in a loop.

To fix this issue, you can try the following:

  1. Add a sleep timer between each curl command to give the system time to recover:
sleep 1 # wait for 1 second
  1. Use a loop to iterate over multiple DNS records:
for record in "${dns_records[@]}"
do
    curl -X PUT "https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/$record" \
         -H "X-Auth-Email: {my_email}" \
         -H "X-Auth-Key: {global_api_key}" \
         -H "Content-Type: application/json" \
         --data '{"type":"A","name":"{domain_name}","content":"'$NEW_IP'","ttl":1,"proxied":true}'
    sleep 1 # wait for 1 second
done

Replace {dns_records[@]} with an array of DNS record IDs, and update the curl command accordingly.

  1. Increase the system’s limit for maximum number of child processes by running the following command:
ulimit -u unlimited

Add this command to the beginning of your script.

Note: increasing the limit may not be recommended as it can lead to other issues with system performance.