Manual_Dicas e truques de script - MikroTik Wiki.pdf

astorheitor 83 views 12 slides Jun 30, 2024
Slide 1
Slide 1 of 12
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12

About This Presentation

os


Slide Content

Manual: dicas e truques de script
Não use números de console para obter valores de parâmetros
Por que find não funciona mesmo se o valor correto for especificado?
Como definir uma matriz vazia
Como remover variáveis
Obter valores para propriedades se o comando 'get' não estiver disponível
Sempre verifique qual valor e tipo o comando retorna
Tenha cuidado ao adicionar array a string
Obter/Definir elementos sem nome em array
Definir valor do elemento em matriz 2D
Ler valor de variável global definida em outro script
Acessando variável global a partir de função
Executando função de outra função
Sempre use nomes de variáveis ​​exclusivos
Obter valores de comandos interativos em loop como "monitor"
Obter conteúdo do arquivo recebido pela ferramenta de busca
Verifique as permissões do script
Tenha cuidado ao usar don't-require-permissions
Vamos começar com o básico. Quando você trabalha com console para acessar parâmetros, você está acostumado a seguir a sintaxe:
Conteúdo
Não use números de console para obter valores de parâmetros

[admin@rack1_b34_CCR1036] /interface> imprimir
Bandeiras: D - dinâmico, X - desabilitado, R - em execução, S - escravo
# NOME TIPO MTU REAL L2MTU MÁXIMO L2MTU
0 R éter1 éter 1500 1580 1022
[admin@rack1_b34_CCR1036] /interface> definir 0 nome=LAN
O que o comando print faz é salvar temporariamente o buffer com números de ID referenciando números de ID internos, então, obviamente, se você estiver
tentando usar valores de buffer inexistentes, o script falhará, como, por exemplo, este script:
/script do sistema adicionar nome=script1 fonte={
/ip route set 0 gateway=3.3.3.3
}
O script não sabe o que você assume como "1" e gerará um erro. A maneira correta é usar números de ID internos, esses números podem ser vistos se você
estiver fazendo print as-valueou retornados pelo comando find, por exemplo:
[admin@rack1_b34_CCR1036] /ip route> :put [encontre onde dst-address="10.0.0.0/8"]
*1
Então, neste caso, o script correto seria:
/script do sistema adicionar nome=script1 fonte={
/ip conjunto de rotas *1 gateway=3.3.3.3
}
Observe que não é recomendado usar números internos diretamente, pois os itens podem ser removidos e adicionados novamente, caso em que o número de
identificação interno será alterado e o script falhará novamente, então, em vez disso, use o comando find diretamente em seu código:
/script do sistema adicionar nome=script1 fonte={
/ip route set [encontrar endereço-de-data-de-navegação="0.0.0.0/0"] gateway=3.3.3.3
}
Digamos que queremos imprimir um endereço específico:
Por que find não funciona mesmo se o valor correto for especificado?

[admin@rack1_b34_CCR1036] /endereço IP> imprimir onde endereço=111.111.1.1/24
Sinalizadores: X - desabilitado, I - inválido, D - dinâmico
# INTERFACE DE REDE DE ENDEREÇO
Então, por que não funciona?
O console tenta converter tipos de variáveis ​​o máximo que pode, mas nem sempre é possível fazer isso corretamente, então vamos analisar de perto por que
esse exemplo em particular não funciona. Primeiro, vamos verificar qual é o tipo de variável "address":
[admin@rack1_b34_CCR1036] /endereço IP> :put [:typeof ([imprimir como valor]->0->"endereço")]
str
Então, obviamente, estamos comparando string com ip-prefix. E a conversão de ip-prefix para string não acontece, então o que podemos fazer para resolver
o problema? Converter variável para o formato correto:
[admin@rack1_b34_CCR1036] /endereço IP> imprimir onde endereço=[:tostr 111.111.1.1/24]

Sinalizadores: X - desabilitado, I - inválido, D - dinâmico
# INTERFACE DE REDE DE ENDEREÇO
0 111.111.1.1/24 111.111.1.0 éter2
Ou use string diretamente:
[admin@rack1_b34_CCR1036] /endereço IP> imprimir onde endereço = "111.111.1.1/24"

Sinalizadores: X - desabilitado, I - inválido, D - dinâmico
# INTERFACE DE REDE DE ENDEREÇO
0 111.111.1.1/24 111.111.1.0 éter2
Obviamente, o segundo método não é adequado se você estiver obtendo o prefixo IP de uma variável. Então, a conversão deve ser feita como no primeiro
exemplo ou escrevendo a variável na string com "$myVar".
O RouterOS não permite definir um array vazio da maneira que você acha que deveria funcionar:
[admin@1p_DUT_wAP ac] /interface>:matriz global {}
erro de sintaxe (linha 1 coluna 17)
Como definir uma matriz vazia

Em vez disso, uma solução alternativa é converter uma string vazia em uma matriz:
[admin@rack1_b36_CCR1009] > :matriz global [:toarray ""]
[admin@rack1_b36_CCR1009] >: impressão do ambiente
matriz={}
A partir daqui podemos usar este array para definir elementos:
[admin@rack1_b36_CCR1009] > :set ($array->"el0") "el0_val"
[admin@rack1_b36_CCR1009] > :impressão de ambiente
matriz={el0="el0_val"}
Você pode usar /system script environment removepara remover variáveis ​​não utilizadas, porém o método mais preferido é desconfigurar a variável.
Definir nenhum valor para um parâmetro existente irá desconfigurá-lo, veja o exemplo abaixo:
[admin@MikroTik] /ambiente de script do sistema> :global myVar 1
[admin@MikroTik] /ambiente de script do sistema> imprimir
# NOME VALOR
0 minhaVar 1
[admin@MikroTik] /ambiente de script do sistema> :set myVar
[admin@MikroTik] /ambiente de script do sistema> imprimir
# NOME VALOR
[admin@MikroTik] /ambiente de script do sistema>
Por exemplo, como você obtém uma saída utilizável para scripts a partir do /interface wireless info hw-infocomando? Use como valor :
[admin@1p_DUT_wAP ac] /interface informações sem fio> :put [hw-info wlan1 como valor]
intervalos=2312-2732/5/b;g;gn20;gn40;2484-2484/5/b;g;gn20;gn40;cadeias-rx=0;1;cadeias-tx=0;1
A saída é uma matriz 1D para que você possa obter facilmente o valor da propriedade de interesse
Como remover variáveis
Obter valores para propriedades se o comando 'get' não estiver disponível

[admin@1p_DUT_wAP ac] /interface informações sem fio> :put ([hw-info wlan1 como-valor ]->"tx-chains")
0;1
Digamos que queremos obter o gateway de uma rota específica usando as-value , se executarmos o seguinte comando ele não retornará nada
[admin@rack1_b36_CCR1009] /endereço IP> :put ([/ip route imprimir como valor onde gateway="ether1"]->"gateway")
O comando assume que a saída será uma matriz 1D da qual poderemos extrair o elemento gateway .
Primeiro, vamos verificar se print realmente encontra alguma coisa:
[admin@rack1_b36_CCR1009] /endereço ip> :put ([/rota ip imprimir como valor onde gateway="ether1"])
.id=*400ae12f;distância=255;dst-address=111.111.111.1/32;gateway=ether1;pref-src=111.111.111.1
Então, obviamente, há algo errado com a própria variável ou com o tipo de variável retornado. Vamos verificar mais de perto:
[admin@rack1_b36_CCR1009] /endereço IP> :global aa ([/ip route imprimir como valor onde gateway="ether1"
])
[admin@rack1_b36_CCR1009] /endereço ip> :ambiente imprimir
aa={{.id=*400ae12f; distância=255; endereço dst=111.111.111.1/32; gateway={"ether1"}; preferência-src = 111,11
1.111.1}}
Agora está claro que o valor retornado é um array 2D com um elemento. Portanto, a sequência correta para extrair o gateway será:
obter matriz 2d
pegue o primeiro elemento
obtenha "gateway" do elemento escolhido
Sempre verifique qual valor e tipo o comando retorna

[admin@rack1_b36_CCR1009] /endereço IP> :put ([:pick [/rota IP imprimir como valor onde gateway="ether1"] 0]->"gateway")
éter1
Se você quiser imprimir um array ou adicionar um array a uma string existente, tenha muito cuidado, pois isso pode levar a resultados inesperados. Por
exemplo, temos um array com dois elementos e queremos imprimir o valor do array na tela:
[admin@1p_DUT_wAP ac] /> :matriz global {"cccc", "ddddd"}
[admin@1p_DUT_wAP ac] /> :put ("o valor da matriz é: ". $array)
o valor da matriz é: cccc; o valor da matriz é: ddddd
Obviamente não era isso que esperávamos, porque o que . faz é adicionar string a cada elemento da matriz e depois imprimir a saída. Em vez disso, você
precisa primeiro converter para string:
[admin@1p_DUT_wAP ac] /> :put ("o valor da matriz é: " . [:tostr $array] )
o valor da matriz é: cccc;ddddd
Digamos que temos um array de elementos { "el1"; "el2"; "el3" }. É possível escolher elementos de um array com o comando pick, mas não é tão simples
quanto a sintaxe abaixo:
[admin@1p_DUT_wAP ac] /> :teste global { "el1"; "el2"; "el3" }
[admin@1p_DUT_wAP ac] /> :put ($teste->1)
el2
A mesma sintaxe pode ser usada para definir valores:
[admin@1p_DUT_wAP ac] /> :set ($test->2) "el3_changed"
[admin@1p_DUT_wAP ac] /> :impressão de ambiente
teste={"el1"; "el2"; "el3_changed"}
Tenha cuidado ao adicionar array a string
Obter/Definir elementos sem nome em array

A sintaxe usada no exemplo acima também pode ser usada para definir o valor do elemento em uma matriz 2D:
[admin@1p_DUT_wAP ac] /> :teste global {{"11";"12";"13"};{"21";"22";"23"}}
[admin@1p_DUT_wAP ac] > :set ($test->1->1) "22_changed"
[admin@1p_DUT_wAP ac] > :colocar [($teste->1->1)]
22_alterado
[admin@1p_DUT_wAP ac] >: impressão do ambiente
teste={{"11"; "12"; "13"}; {"21"; "22_alterado"; "23"}}
Digamos que temos um script que declara uma variável e define o valor:
/script do sistema adicionar nome=script1 fonte={
:global myVar "olá!"
}
E queremos escrever o valor dessa variável no log de outro script. A simples adição /log info $myVarnão retornará o valor correto, porque o segundo
script não sabe nada sobre as variáveis ​​definidas em outros scripts. Para que funcione corretamente, a variável precisa ser definida, então o segundo código
de script correto é:
/script do sistema adicionar nome=script2 fonte={
:global minhaVar;
:log info "o valor é: $myvar"
}
Logicamente, você pensaria que variáveis ​​definidas globalmente também deveriam ser acessíveis em funções, mas esse não é realmente o caso. Vejamos um
exemplo:
Definir valor do elemento em matriz 2D
Ler valor de variável global definida em outro script
Acessando variável global a partir de função

:global minhaVar "teste"
:global minhaFunc do={
:coloque "var global=$minhaVar"
}
[$minhaFunção]
A saída é:
var global=
Obviamente, a variável global não é acessível diretamente. Para que funcione, precisamos declarar a variável global dentro da função:
:global minhaVar "teste"
:global minhaFunc do={
:global minhaVar;
:coloque "var global=$minhaVar"
}
[$minhaFunção]
Saída:
var global=teste
O mesmo que acima se aplica também a funções. Se você quiser executar uma função de outra função, então ela precisa ser declarada.
:teste global fazer={
:retorno ($1 + 1)
}
:teste globalteste do={
:local x 5
:local y [$teste $x]
:coloque "tipo de = $[:tipo de $y]"
:coloque "testets_res=$y"
}
O código acima não funcionará conforme o esperado, a saída será:
Executando função de outra função

tipo de = nulo
testes_res=
Para corrigir isso, precisamos declarar o "teste" global na função "testtest"
:teste globalteste do={
:teste global
:local x 5
:local y [$teste $x]
:coloque "tipo de = $[:tipo de $y]"
:coloque "testets_res=$y"
}
Um dos erros de script mais comuns que a maioria dos usuários comete é não usar nomes de variáveis ​​exclusivos, por exemplo, a variável definida na função
tem o mesmo nome que a variável definida globalmente, o que leva a resultados inesperados:
:global meu2 "123"
:global minhaFunc do={ :global minha2; :coloque $meu2; :set my2 "lala"; :coloque $meu2 }
$minhaFunção meu2=1234
:put "valor global $my2"
A saída será:
1234
lalá
valor global 123
Outro caso comum é quando a variável definida pelo usuário tem o mesmo nome da variável incorporada do RouterOS, por exemplo, queremos imprimir a
rota com o endereço dst definido na variável:
[admin@1p_DUT_wAP ac] /ip route> :global "endereço-dst" "0.0.0.0/0"
[admin@1p_DUT_wAP ac] /ip route> print onde dst-address=$"dst-address"
Sinalizadores: X - desabilitado, A - ativo, D - dinâmico, C - conectar, S - estático, r - rip, b - bgp, o - ospf, m - mme,
B - buraco negro, U - inacessível, P - proibir
# DST-ENDEREÇO ​​PREF-SRC DISTÂNCIA DO GATEWAY
0 ANÚNCIOS 0.0.0.0/0 10.155.136.1 1
Sempre use nomes de variáveis ​​exclusivos

1 ADC 10.155.136.0/24 10.155.136.41 éter1 0
Obviamente o resultado não é o esperado, solução simples, use nome de variável exclusivo:
[admin@1p_DUT_wAP ac] /rota ip> :global myDst "0.0.0.0/0"
[admin@1p_DUT_wAP ac] /ip route> print onde dst-address=$myDst
Sinalizadores: X - desabilitado, A - ativo, D - dinâmico, C - conectar, S - estático, r - rip, b - bgp, o - ospf, m - mme,
B - buraco negro, U - inacessível, P - proibir
# DST-ENDEREÇO ​​PREF-SRC DISTÂNCIA DO GATEWAY
0 ANÚNCIOS 0.0.0.0/0 10.155.136.1 1
Perguntas frequentes sobre como obter valores no script retornados por, por exemplo, comando monitor ? O primeiro problema com tais comandos é que
eles são executados infinitamente até que a ação do usuário seja aplicada, obviamente você não pode fazer isso a partir do script. Em vez disso, você pode
executar com parâmetro adicional once , isso permitirá executar o comando apenas uma vez e parar. Outro problema é obter o valor da variável sin script,
não há as-value , não há get , mas eles têm do . O que ele faz é permitir o acesso às variáveis ​​retornadas pelo comando como no exemplo abaixo:
[admin@1p_DUT_wAP ac] /interface> monitor-traffic ether1 uma vez do={:global myBps ​​$"rx-bits-per-second" }
...
[admin@1p_DUT_wAP ac] /interface>: impressão de ambiente
meusBps=71464
A ferramenta Fetch permite a facilidade de uso ao baixar o conteúdo do arquivo na memória e permitir o acesso a esses dados por script. Para fazê-la
funcionar, use o parâmetro as-value e output=user :
[admin@rack1_b34_CCR1036] > :put ([/tool ​​fetch ftp://admin:@10.155.136.41/test.txt
saída=usuário como valor ]->"dados")
conteúdo do meu arquivo
Obter valores de comandos interativos em loop como "monitor"
Obter conteúdo do arquivo recebido pela ferramenta de busca

Digamos que temos um script que cria e grava conteúdo no arquivo:
/script do sistema adicionar nome=script1 política=ftp,leitura,gravação fonte={
/arquivo imprimir arquivo=teste;
/file set test.txt content="meu conteúdo"
}
Agora vamos adicionar um agendador que tentará executar este script:
/ agendador do sistema
adicione intervalo = 10s nome = teste on-event = script2 política = leitura, gravação
Então agora esperamos 10 segundos, o arquivo não foi criado, esperamos mais 10 segundos e ainda não há arquivo. O que está acontecendo? Se você olhar
atentamente, o script requer a política "ftp" para criar um arquivo, mas o planejador tem apenas as políticas "read" e "write", então o script não será
executado. A correção é definir o planejador para executar com as políticas corretas "read,write,ftp".
Isso se aplica também se você estiver tentando executar scripts do netwatch, ppp on event e assim por diante, que são limitados a políticas específicas de
"leitura, gravação, teste, reinicialização", portanto você não poderá executar scripts avançados que criam backups, cria arquivos e assim por diante.
A limitação pode ser corrigida usando dont-require-permissions , mas tenha muito cuidado, leia abaixo.
É possível definir script com o parâmetro dont-require-permissions . Basicamente, ele permite que qualquer pessoa sem permissões adequadas execute
o script. Por exemplo, se o script tem políticas "read,write,test,sensitive", mas o usuário ou aplicativo que executa o script tem menos, por exemplo,
"read,write", então a configuração dont-require-permissions=yespermitirá executar o script de qualquer maneira.
Isso poderia permitir a alteração de informações confidenciais usando script, mesmo que o usuário não tenha permissões suficientes.
[ Topo | Voltar ao conteúdo ]
Retrieved from "https://wiki.mikrotik.com/index.php?title=Manual:Scripting_Tips_and_Tricks&oldid=32599"
Verifique as permissões do script
Tenha cuidado ao usar don't-require-permissions

Esta página foi editada pela última vez em 3 de janeiro de 2019, às 12h39.
Tags