First of all @rextended thank you for the detailed explanation(s) in your post. It helped me progress debugging this.
I tested your example code and the $variablename certainly does remove the syntax error from the :set command, but the set command does not work as expected. Its like it sets the value of an undeclared local variable of the same name as the global, but does not change the value of the global variable.
See this screen shot (Imgur: The magic of the Internet) for color coding, note the variable after :set is showing as undeclared.
This is your example code with some :put commands that I added within each layer, note the 3rd put is missing the variable value on the output.
[admin@MikroTik] > /system script
[admin@MikroTik] /system script> add name=rosinit dont-require-permissions=no owner=admin policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source={
{... :global ghwmodel
{... :global ghwname
{... :global fdeviceconfig do={
{{... :if ([/system routerboard get routerboard] = true) do={
{{{... :set $ghwname [/system routerboard get board-name]
{{{... :put "1 HW name $ghwname"
{{{... }
{{... :put "2 HW name $ghwname"
{{... }
{... $fdeviceconfig
{... :put "3 HW name $ghwname"
{... }
[admin@MikroTik] /system script> /system script print
Flags: I - invalid
0 name="rosinit" owner="admin" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon dont-require-permissions=no run-count=0 source=
:global ghwmodel
:global ghwname
:global fdeviceconfig do={
:if ([/system routerboard get routerboard] = true) do={
:set $ghwname [/system routerboard get board-name]
:put "1 HW name $ghwname"
}
:put "2 HW name $ghwname"
}
$fdeviceconfig
:put "3 HW name $ghwname"
[admin@MikroTik] /system script> /system script run rosinit
1 HW name cAP ac
2 HW name cAP ac
3 HW name
[admin@MikroTik] /system script>
This testing is on one cAP ac (RBcAPGi-5acD2nD) running 6.48.3 (stable) of RouterOS. Connected via SSH.
So that helped but wasn't a functional fix, and it irked me that the need for a $ was was contray to the Mikrotik documentation in the wiki RouterOS - RouterOS - MikroTik Documentation
But it did help me debug it. I have fixed the issue be re-delaring global variables and functions within the functions, even through it has to be re-declared within the context of the function it is keeping the value of the global variable that is set outside the function... a little weird but it works
For example
:global ghwmodel
:global ghwname
:global fdeviceconfig do={
:global ghwname
:if ([/system routerboard get routerboard] = true) do={
:set $ghwname [/system routerboard get board-name]
:put "1 HW name $ghwname"
}
:put "2 HW name $ghwname"
}
$fdeviceconfig
:put "3 HW name $ghwname"
Since RouterOS supports both gobal and local variables I found it weird that global ≠ all contexts within the script/session/device, but that seems to be the answer as the script is working perfectly now. As functions are also a :global declaration the same was true for them (i.e. I needed to re-declare the function names, within each function that invoked them), this included where a line within the function invokes itself (think a function with multiple sub-functions where the sub-functions may use each other). Confusing ciruclar logic? yes, but it works.
Thanks for your help