I’m hitting a challenging bug or behavior where running a script provokes a prompt for "value:" instead of completing. This only happens with certain scripts. I can’t figure out why.
Here are a few code samples to illustrate, which can be run from the Terminal in webfig to provoke the behavior. I have posted "working" (versions that complete normally) and "not working" (versions that go to "value:" prompt). I can therefore reproduce it in a few ways but I can't discern any logic or way to counter it.
I am completely dead in the water on my project due to this. I cannot figure out any reliable way to work around it.
Have you experienced this before? Is it a known bug? Is there some rational way around it? How can I make my code work?
I posted the script I am trying to make work at the bottom to illustrate. I have spent 5-8+ hours now with ChatGPT and Grok trying to figure this out, and I am no further ahead.
Thanks for any help. (/system resource print = version: 7.15.2 (stable))
Set up Temp Script
You can run this line to set up the temp script, then just copy and paste any code block below in after to run them.
Code: Select all
/system script add name=cloudflare_ddns policy=read,write,test source=""
EXAMPLE 1
==============
DOESN'T WORK
==============
Code: Select all
/system script set cloudflare_ddns source={
:local ipCheckURL "http://api.ipify.org";
:local currentIP;
:do {
:set currentIP [/tool fetch url=$ipCheckURL output=user as-value];
:return;
} on-error={
:log warning "Fetch failed";
:return;
};
:local noop "done"
};
/system script run cloudflare_ddns;
WORKS
==============
Code: Select all
/system script set cloudflare_ddns source={
:local result;
:do {
:set result [/tool fetch url="http://api.ipify.org" output=user as-value];
} on-error={
:log warning "fail";
};
:local noop "done"
};
/system script run cloudflare_ddns;
EXAMPLE 2
================================
DOESN'T WORK:
================================
Code: Select all
/system script set cloudflare_ddns source={
:local cfSubdomain "www";
:local cfZoneName "google.com";
:local cfDomain ($cfSubdomain . "." . $cfZoneName);
:local ipCheckURL "http://api.ipify.org";
:local currentIP;
:local unused [:do {
:set currentIP [/tool fetch url=$ipCheckURL output=user as-value];
} on-error={
:log warning "Cloudflare DDNS: Failed to fetch public IP from $ipCheckURL - skipping update.";
}];
:if ($currentIP = "") do={
:log warning "Cloudflare DDNS: Empty response from IP check - skipping update.";
:return;
};
:local newIP ($currentIP->"data");
:set newIP [:pick $newIP 0 [:find $newIP "\n" -1]];
:local ipParsed [:toip $newIP];
:local ipLength [:len $ipParsed];
:if ($ipLength = 0) do={
:log warning "Cloudflare DDNS: Invalid IP detected: $newIP - skipping update.";
:return;
};
};
/system script run cloudflare_ddns;
================================
WORKS:
================================
Code: Select all
/system script set cloudflare_ddns source={
:local cfSubdomain "www";
:local cfZoneName "google.com";
:local cfDomain ($cfSubdomain . "." . $cfZoneName);
:local ipCheckURL "http://api.ipify.org";
:local currentIP;
:local unused [:do {
:set currentIP [/tool fetch url=$ipCheckURL output=user as-value];
} on-error={
:log warning "Cloudflare DDNS: Failed to fetch public IP from $ipCheckURL - skipping update.";
}];
:if ($currentIP = "") do={
:log warning "Cloudflare DDNS: Empty response from IP check - skipping update.";
:return;
};
:local newIP ($currentIP->"data");
:set newIP [:pick $newIP 0 [:find $newIP "\n" -1]];
:local ipParsed [:toip $newIP];
:local ipLength [:len $ipParsed];
};
/system script run cloudflare_ddns;
REAL CODE I AM TRYING TO MAKE WORK
For reference, this is what I'm trying to do - a script to update cloudflare DNS from the public dynamic IP. I think it should be simple enough but I can't get past this behavior. Thanks again for any help.
Code: Select all
/system script set cloudflare_ddns source={
:local cfSubdomain "subdomain";
:local cfZoneName "domain.com";
:local cfZoneID "zoneid";
:local cfToken "token";
:local cfDomain ($cfSubdomain . "." . $cfZoneName);
:local ipCheckURL "http://api.ipify.org";
:local currentIP;
:local unused [:do {
:set currentIP [/tool fetch url=$ipCheckURL output=user as-value];
} on-error={
:log warning "Cloudflare DDNS: Failed to fetch public IP from $ipCheckURL - skipping update.";
}];
:if ($currentIP = "") do={
:log warning "Cloudflare DDNS: Empty response from IP check - skipping update.";
:return;
};
:local newIP ($currentIP->"data");
:set newIP [:pick $newIP 0 [:find $newIP "\n" -1]];
:local ipParsed [:toip $newIP];
:local ipLength [:len $ipParsed];
:if ("$ipLength" = 0) do={
:log warning "Cloudflare DDNS: Invalid IP detected: $newIP - skipping update.";
:return;
};
:local apiURL "https://api.cloudflare.com/client/v4/zones/$cfZoneID/dns_records?type=A&name=$cfDomain";
:local result;
:local headerField ("Authorization: Bearer $cfToken, Content-Type: application/json");
:local unused [:do {
:set result [/tool fetch url=$apiURL http-method=get output=user http-header-field=$headerField check-certificate=yes as-value];
} on-error={
:log warning "Cloudflare DDNS: Failed to reach Cloudflare API for lookup - skipping update.";
}];
:if ($result = "") do={
:log warning "Cloudflare DDNS: Empty response from API lookup - skipping update.";
:return;
};
:local response ($result->"data");
:if ([:len $response] = 0) do={
:log info "Cloudflare DDNS: No A record for $cfDomain - creating new one...";
:local postData ("{\"type\":\"A\",\"name\":\"" . $cfDomain . "\",\"content\":\"" . $newIP . "\",\"ttl\":120,\"proxied\":false}");
:local unused [:do {
/tool fetch url="https://api.cloudflare.com/client/v4/zones/$cfZoneID/dns_records" http-method=post http-header-field=$headerField http-data=$postData check-certificate=yes output=none;
:log info "Cloudflare DDNS: DNS record created successfully.";
} on-error={
:log warning "Cloudflare DDNS: Failed to create DNS record.";
}];
:return;
};
:local cfRecord [:pick $response 0];
:local recordID ($cfRecord->"id");
:local oldIP ($cfRecord->"content");
:if ($newIP != $oldIP) do={
:log info "Cloudflare DDNS: IP changed from $oldIP to $newIP - updating...";
:local putData ("{\"type\":\"A\",\"name\":\"" . $cfDomain . "\",\"content\":\"" . $newIP . "\",\"ttl\":120,\"proxied\":false}");
:local unused [:do {
/tool fetch url="https://api.cloudflare.com/client/v4/zones/$cfZoneID/dns_records/$recordID" http-method=put http-header-field=$headerField http-data=$putData check-certificate=yes output=none;
:log info "Cloudflare DDNS: DNS record updated successfully.";
} on-error={
:log warning "Cloudflare DDNS: Failed to update DNS record.";
}];
} else={
:log info "Cloudflare DDNS: IP unchanged ($newIP), no update needed.";
};
};
/system script run cloudflare_ddns;