Значение переменной вывести в название другой переменной.

Здесь выкладываем скрипты
Правила форума
Уважаемые Пользователи форума, обратите внимание!
Ни при каких обстоятельствах, Администрация форума, не несёт ответственности за какой-либо, прямой или косвенный, ущерб причиненный в результате использования материалов, взятых на этом Сайте или на любом другом сайте, на который имеется гиперссылка с данного Сайта. Возникновение неисправностей, потерю программ или данных в Ваших устройствах, даже если Администрация будет явно поставлена в известность о возможности такого ущерба.
Просим Вас быть предельно осторожными и внимательными, в использовании материалов раздела. Учитывать не только Ваши пожелания, но и границы возможностей вашего оборудования.
Аватара пользователя
podarok66
Модератор
Сообщения: 4355
Зарегистрирован: 11 фев 2012, 18:49
Откуда: МО

Я могу только предположить, что в вашем варианте запроса получаемый ответ выдается не в виде числа,а какого-то единого значения. Потому как если взять длину значения в вашем случае, будет единица.

Код: Выделить всё

:global rxbyte [/interface ethernet get WAN rx-bytes];
:put $rxbyte;
17 575 300 924
:put [:len $rxbyte]
1

В моём варианте будет именно числовое значение, и его длина будет совсем не такой:

Код: Выделить всё

:global rxbyte [/interface get [find name=WAN] rx-byte]   
 :put $rxbyte                                           
17575300924
:put [:len $rxbyte]
11

А в целом, примите это как данность и не парьтесь. Я сам не знаю, почему всё именно так, а не иначе :-)


Мануалы изучил и нигде не ошибся? Фаервол отключил? Очереди погасил? Витая пара проверена? ... Тогда Netinstal'ом железку прошей и настрой ее заново. Что, все равно не фурычит? Тогда к нам. Если не подскажем, хоть посочувствуем...
enternight
Сообщения: 6
Зарегистрирован: 01 сен 2017, 11:57

еще раз выражаю вам огромную благодарность
данность принята на вооружение :ps_ih:


Аватара пользователя
podarok66
Модератор
Сообщения: 4355
Зарегистрирован: 11 фев 2012, 18:49
Откуда: МО

Да не за что, собственно. Вы спрашивайте, если будет надобность. В кои-то веки посетитель подкинул интересный вопрос, я хоть покопался немного для своего удовольствия.


Мануалы изучил и нигде не ошибся? Фаервол отключил? Очереди погасил? Витая пара проверена? ... Тогда Netinstal'ом железку прошей и настрой ее заново. Что, все равно не фурычит? Тогда к нам. Если не подскажем, хоть посочувствуем...
Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

А на первоначальный вопрос не ответили так и ...

Допустим есть переменная $key значение которой меняется ... (пусть хоть от 1 до 10 или буквенные различные)
Следующей командой создаем переменную с именем lte$key

:parse [:execute ":global lte$key ({})"]

Нужная переменная в окружении создается, это видно в environment, но как ей оперировать - то есть имя ее итоговое то мы так и не знаем !
Как ей например присваивать значения ?


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

более того, если зная $key попытаться получить :type переменной, составленной из lte + $key (допустим lte1) то получаем nothing !
То есть в окружении переменная создалась, но реально ее нет. Не помогает и предварительное преобразования $key в строковое значение.
Очень странно.

Такая задача нужна была бы ну например - Вы ищете скриптом что-либо не зная заранее результат этих поисков.
Я, например, пытаюсь искать lte-интерфейсы на Микротике. Если я нахожу, то хочу создать массив, имеющий имя равное имени lte-интерфейса, а потом загнать в него параметры из lte info


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

Теперь, кажется, становится понятным в чем дело ... Дело в том, что в самом скрипте, где выполняется
:execute ":global lte$key ({})" создаваемая переменная не объявляется ! То есть, она в окружении создается, то скрипту остаётся не известной.
Это проверяется просто. Допустим $key это "1"

Тогда:
:execute ":global lte$key ({})"
:set $lte1 "test"
выполнено не будет, т.к. $lte1 не объявлена и не известна, а

:execute ":global lte$key ({})"
:global lte1
:set $lte1 "test"

работает.

Как тут быть не понятно.


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
Аватара пользователя
podarok66
Модератор
Сообщения: 4355
Зарегистрирован: 11 фев 2012, 18:49
Откуда: МО

Таблица из вложения не поможет? Там вроде как всё очень скрупулёзно человек просмотрел. Если что, по названию файла поиск в гугле должен привести к статье на хабре, где и позаимствована табличка...
Вложения
Исследование объявлений переменных.xlsx
(17.5 КБ) 439 скачиваний


Мануалы изучил и нигде не ошибся? Фаервол отключил? Очереди погасил? Витая пара проверена? ... Тогда Netinstal'ом железку прошей и настрой ее заново. Что, все равно не фурычит? Тогда к нам. Если не подскажем, хоть посочувствуем...
Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

За табличку спасибо. Я этот текст и исследование переменных знаю.
Дело не в этом, кажется.

Дело в том что если делаем из скрипта :execute ":global $Var" или :parse [:execute ":global $Var"] (как предложил когда то vqd) переменная с именем равным значению переменной $Var в окружении действительно создается !, но скрипт, который это делает всё равно "ничего о ней не знает", т.к. она остается для него как бы не объявленной и оперировать ей нельзя !
А сделать прямо :global $Var из скрипта естественно нельзя - "синтаксическая ошибка", т.к. "$" автоматически означает "значение" переменной.

Вот и получается, что создать переменную с именем равным значению переменной из скрипта как бы можно (см. абзац 1), а пользоваться ей нельзя пока её не объявить снова через :global, но точно указав её имя. Можете попробовать сами. То есть :execute переменную создает как бы именно в "фоновом" режиме, в обход какой-то важной подпрограммы РОС, которая объявляет её !

Это ограничение, вероятно, скриптового языка РОС. Не знаю с какой целью это сделано, вероятно цель была ...
Если кто опровергнет и найдет способ создать переменную с именем равным значению другой переменной, но так, чтобы она стала доступна из скрипта - буду только рад ...

Интересно, что переменные созданные путем :execute ":global $Var скрипту не известны, а консоли - да, можно попробовать :log info $Var и :put $Var. В первом случае получим етественно ничего, а :put значение выводит, что логично - созданная в "фоновом" режиме переменная системе известна, а скрипту нет, т.к. в нем не объявлена.

Вот тут viewtopic.php?f=14&t=9180 похожая тема уже обсуждалась, но рассматривались другие типы создания переменных ... (не с именем равным значению), тоже может быть полезно.

Написал с горя в support mikrotik, поглядим что ответят ... А вот и ответ прилетел:


Hello,

RouterOS scripting does not support declaring variables which names are taken from another variables value.
Regarding your question, variable is not declared in current scope, that is why you cannot get its value until ;global varname; is added to the script.

Best regards,
Maris B.

Что, собственно, и следовало ожидать. Так, что извращения вида :parse [:execute ":global $Var"] ,увы, бессмыссленны.

Вопрос исследован и закрыт.


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
deniseik
Сообщения: 1
Зарегистрирован: 13 фев 2024, 21:46

Нашел способ!

Запись переменной:

Код: Выделить всё

local x "X"
local y "Y"
execute "global $x $y"
Чтение переменной:

Код: Выделить всё

local z
foreach i in=[sys/scr/env find] do {
	if ($x=[sys/scr/env get $i name]) do {
		set z [sys/scr/env get $i value]
	}
}


Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

Похвально, но:

1. Надо проверить Ваше решение
2. Из Вашего решения получается, чтобы работать с одной переменной нужно перебрать все переменные в окружении, что не оправдано затратно по ресурсам процессора
3. Если искать решение - оно должно быть другим ... (без цикла перебора всех переменных ...)
4. И, по крайней мере уж как-то так (систаксис не проверял) .... чтобы хоть понятно было программисту откуда ноги растут ...
5. Сокращать команды ROS в скриптах (если это ещё не продакшен :-):) не стоит, вне зависимости от синтаксиса версии (6 или 7 не важно), так как потом сами запутаетесь и вспоминать будете что и как написали когда-то ...

Код: Выделить всё

local z
/system script environment

:foreach item in=[:find] do {
         if ($x=[:get $item name]) do={set z [:get $item value]
     }
}


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
Ответить