Update a variable with a function

Hi guys!

I’ve created some scripts at work that abstract the user’s technical configuration and instead just ask questions, the user answers them and the answer is validated.
Everything works perfectly, but now I’m trying to turn these answer validations into functions, as the script is getting long. Take a look below:

# Function - Validating response
        :global checkYN do={while ($a != "y" && $a != "n") do={
            :put "----------------------------------------------------------------------------------------------------"
            :put "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
            :put "                                      ERROR: Invalid response."
            :put "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
            :put "----------------------------------------------------------------------------------------------------"
            
            :local b do={:return}
            :put "\r\n*****                                          y or n                                          *****\r\n"
            :set $a [$b]

            :put "var $a after set inside function"
            }
        }

# Asking if the user want to configure the identity
        :global readIdentity do={:return}
        :put "                            Do you want to configure the Mikrotik identity?
        \r\n*****                                          y or n                                          *****\r\n"
        :global identityResponse [$readIdentity]

	# Calling function
		:put "var $identityResponse raw"
       		$checkYN a=$identityResponse
        	:put "var $identityResponse after function checkYN"

The problem is that the variable I’m passing is not receiving the updated value after the function. It’s the first time I’ve created a function, I think it’s something to do with scopes, but I’ve tried several ways and haven’t managed to solve it.

I appreciate any help :slight_smile:

In recent RouterOS, there is /terminal/ask - so you do not need to use the [:return] trick to do this.

{
:local resp [/terminal/ask prompt="Continue? [y/n]"]
:if ($resp~"^[yY]\$") do={:put "got Y or y"} else={:put "got something else"}
}

There is also /terminal/inkey, which I suspect you want for a confirmation. “inkey” take exact one character, and turned it to a variable.
It also has a timeout, so it can proceed if no key is pressed. Otherwise /terminal/inkey waits for some/any keyboard input.

{
     :local confirmkey [/terminal/inkey timeout=1m] 
     :if ($confirmkey=89 or $confirmkey=121) do={ :put "got Y or y" } else={:put "got something else"}  
}

89 and 121 are the ASCII codes for “A” and “a”, in decimal integers. To map a character to the number needed, the follow will output the number from the keypresses:
:put [/terminal/inkey]

In 7.15, there is new :convert “byte-array” that can be used to convert the ASCII code from /terminal/inkey, back into a alphanumber string type (of one char) .

{
     :local confirmkey [:convert from=byte-array to=raw {[/terminal/inkey]}]
     :if ($confirmkey~"[yY]") do={ :put "got Y or y" } else={:put "got something else"}  
}

Thanks for those tips, Amm0!
Unfortunately, due to internal policies, we only run the LTS versions and apparently the terminal/ask doesn’t work on ROSv6, but I’ll be sure to save this tip to update the scripts when we get to ROSv7.

The “/terminal inkey” exists in V6, with a space.

So this revised example works on 6.49.14:

{
     :local confirmkey [/terminal inkey] 
     :if ($confirmkey=89 or $confirmkey=121) do={ :put "got Y or y" } else={:put "got something else"}  
}