My current workflow involves a lot of copy-pasting to keep my local directory and the scripts on a Mikrotik device in sync.
Is there a better way for this?
If so, what?
(Either Mac OS X or Windows based is fine as I run both)
–jeroen
My current workflow involves a lot of copy-pasting to keep my local directory and the scripts on a Mikrotik device in sync.
Is there a better way for this?
If so, what?
(Either Mac OS X or Windows based is fine as I run both)
–jeroen
FTP.
Get a text editor that can sync up with FTP, and set up an FTP connection with the router that you then sync on when the editor starts, and when you save.
An example of a text editor that I know can do this would be NetBeans, though it doesn’t have any sort of MikroTik specific support, so as it stands, using it is equal to using Notepad… but with FTP syncing in the middle of it. And needless to say there are other editors out there that can do that too (though I haven’t personally used any).
I tried. But none of the things in /system scripts print show up on the FTP server.
What am I missing?
What workflow would you suggest?
–jeroen
I tried. But none of the things in /system scripts print show up on the FTP server.
What am I missing?
What workflow would you suggest?
My current work-flow is this:
/system script environment printUse export command instead of print.
How would that fit in the workflow?
(I must be missing something fundamental here, just not sure what it is yet, so please elaborate).
–jeroen
Point 5. Export to file. Then you can grab it by ftp out.
I tried and got all scripts in one big file in a format that is not friendly for the syntax highlighting in the various text editors (Atom, Sublime, Notepad++). I picked out one, see below.
What I’m looking for is to export each script in a individual file, preferably in a subdirectory (as that’s way easier to sync over FTP: I love Beyond Compare for this) named as they are named in the WinBox script editor and in the same format as that script editor.
With those individual files, I should also be able to get them in a git repository easily.
I also want the other way around: have an updated file from the script repository, FTP it to the Mikrotik then install it.
Any ideas (especially as getting the individual script properties doesn’t work, see below)?
I tried getting the script names, but it fails at the :get, indicating bad command name get (line 1 column 114)
:foreach scriptId in [/system script find] do={ :local script [/system script get $scriptId]; :local scriptName [:get $script name]; :put $scriptName }
bad command name get (line 1 column 114)
The $script variable holds each script with their properties, as this dumps all properties:
:foreach scriptId in [/system script find] do={ :local script [/system script get $scriptId]; :put $script }
Example of export (this is a fragment of /system script export file=scripts.rsc):
add name=Function.startsWithString.rsc owner=admin policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive source=":global startsWithString do={\r\
\n # returns true if \$value starts with \$subString\r\
\n\r\
\n#global varDump\r\
\n\r\
\n#:put \"value=\"\r\
\n#\$varDump value=\$value\r\
\n#:put \"subString=\"\r\
\n#\$varDump value=\$subString\r\
\n \r\
\n :local result false\r\
\n#:put \"result=\"\r\
\n#\$varDump value=\$result\r\
\n\r\
\n :if ([:typeof \$value] = \"str\") do={\r\
\n :if ([:typeof \$subString] = \"str\") do={\r\
\n :local valueLength [:len \$value]\r\
\n :local subStringLength [:len \$subString]\r\
\n :if (\$valueLength > \$subStringLength) do={\r\
\n# strings start at position zero (0)!\r\
\n# 01234\r\
\n# ABCDE -> length 5\r\
\n# AB -> length 2; positions 0..1\r\
\n\r\
\n :local valueStart (0)\r\
\n # bug that won't be fixed: :pick end parameter is 1-based, not 0-based http://forum.mikrotik.com/viewtopic.php\?t=108311\r\
\n # :local valueEnd (\$subStringLength - 1)\r\
\n :local valueEnd (\$subStringLength - 0)\r\
\n :local valuePick [:pick \$value \$valueStart \$valueEnd] \r\
\n#:put \"valueStart=\"\r\
\n#\$varDump value=\$valueStart\r\
\n#:put \"valueEnd=\"\r\
\n#\$varDump value=\$valueEnd\r\
\n#:put \"valuePick=\"\r\
\n#\$varDump value=\$valuePick \r\
\n :set \$result (\$subString = \$valuePick)\r\
\n }\r\
\n }\r\
\n };\r\
\n\r\
\n#:put \"result=\"\r\
\n#\$varDump value=\$result\r\
\n :return \$result;\r\
\n}\r\
\n\r\
\n# Examples:\r\
\n# /system script run Function.startsWithString.rsc\r\
\n# :put [\$startsWithString value=\"ABCDE\"]\r\
\n# false\r\
\n# :put [\$startsWithString value=\"ABCDE\" subString=(7)]\r\
\n# false\r\
\n# :put [\$startsWithString value=\"ABCDE\" subString=\"DE\"]\r\
\n# false\r\
\n# :put [\$startsWithString value=\"ABCDE\" subString=\"AB\"]\r\
\n# true\r\
\n"
–jeroen
I have not tried to solve your task. Maybe user Sinan could help you somehow more practically. He seems to be an enthusiast to the ros scripting…
Any file with extension “.rsc” can be ran by RouterOS using the “/import” command. And as jarda already said, you can use “/export” to generate an “.rsc” file that has everything needed to replicate a router configuration.
If you only have a few scripts, I think you’re in a position right now where you can “manually” cut & paste them into “.rsc” files, and after that, at all points you need them, use ‘/import file=“scriptname.rsc”’ instead of ‘/system script run “scriptname”’.
If you have many, you can use something like:
:local scripts [/system script print detail as-value]
#Create pseudo files (RouterOS can't create empty ones at will)
:foreach script in=$scripts do={
/file print file=(($script->"name") . ".rsc")
}
#Wait for the files to be created "for real"
:delay 2s
#Fill the files with the script's contents
:foreach script in=$scripts do={
/file set (($script->"name") . ".rsc") contents=($script->"source")
}
Oh, and for why “get” fails… Remember when I said “get” returns the info as an associative array? Well, I’m stupid, so forget that… I was confusing that with “print as-value”, which is my preferred method (as above), so I forgot that “get” returns an individual property that you must specify alongside the ID/name of the item you’re targeting… Plus, there’s no “:get” command (i.e. no “get” command at the root menu; only menu specific “get” ones).
That fails:
failure: new contents too long
Can you show the contents of a few files exported with your above method? As mine look odd, for instance profile:jeroenp@192.168.71.3?Function.startsWithString.rsc.rsc.txt looks like this:
# may/17/2016 7:26:37 by RouterOS 6.35.1
# software id = VQR4-7MRH
#
# NAME TYPE SIZE CREATION-TIME
0 skins directory jan/01/1970 02:00:03
1 MikroTik-19700102-0... backup 16.0KiB jan/02/1970 02:48:23
2 pub directory jan/02/1970 02:54:47
3 crs226-export.rsc script 357 jan/02/1970 03:46:45
4 console-dump.txt .txt file 16.8KiB may/02/2016 14:53:49
5 DHCP-DNS-work.rsc script 6.1KiB apr/21/2016 22:10:42
6 WAN0-WAN2.rsc script 9.2KiB may/01/2016 11:16:57
7 helden-static-WAN2-... script 9.6KiB may/01/2016 16:39:51
8 dhcp-server-gateway... script 13.8KiB may/01/2016 20:48:51
9 apc-dhcp-option-43-... script 15.6KiB may/02/2016 15:17:02
10 dude dude store may/03/2016 12:25:48
11 udp-67-dhcp file 21.4KiB may/03/2016 16:27:48
12 scripts.rsc script 38.1KiB may/16/2016 08:35:43
13 mikrotik-dns-dhcp.s... .txt file 1270 may/17/2016 07:26:37
14 playground.rsc.txt .txt file 1350 may/17/2016 07:26:37
15 Function.escapeStri... .txt file 1430 may/17/2016 07:26:37
16 Function.stripInval... .txt file 1510 may/17/2016 07:26:37
17 Function.padLeftStr... .txt file 1590 may/17/2016 07:26:37
18 Function.varDump.rs... .txt file 1670 may/17/2016 07:26:37
19 Function.padRightSt... .txt file 1750 may/17/2016 07:26:37
20 Function.endsWithSt... .txt file 1830 may/17/2016 07:26:37
21 Function.startsWith... .txt file 0 may/17/2016 07:26:37
So basically you say that get should have been like this: /system script get right?
Lets try that:
:foreach scriptId in [/system script find] do={ :local scriptName [/system script get $scriptId name]; :put $scriptName }
mikrotik-dns-dhcp.script
playground
Function.escapeString.rsc
Function.stripInvalidHostNameCharactersFromString.rsc
Function.padLeftString.rsc
Function.varDump.rsc
Function.padRightString.rsc
Function.endsWithString.rsc
Function.startsWithString.rsc
That works. Yay!
Some stats that might help with the contents too long:
:foreach scriptId in [/system script find] do={ :local scriptSource [/system script get $scriptId source]; :local scriptSourceLength [:len $scriptSource]; :local scriptName [/system script get $scriptId name]; :put "$scriptSourceLength bytes: '$scriptName'" }
3070 bytes: 'mikrotik-dns-dhcp.script'
6528 bytes: 'playground'
8065 bytes: 'Function.escapeString.rsc'
1938 bytes: 'Function.stripInvalidHostNameCharactersFromString.rsc'
1411 bytes: 'Function.padLeftString.rsc'
2422 bytes: 'Function.varDump.rsc'
1418 bytes: 'Function.padRightString.rsc'
1515 bytes: 'Function.endsWithString.rsc'
1507 bytes: 'Function.startsWithString.rsc'
and
[jeroenp@MikroTikCCR1009] > /file print
# NAME TYPE SIZE CREATION-TIME
0 skins directory jan/01/1970 02:00:03
1 MikroTik-19700102-0048.backup backup 16.0KiB jan/02/1970 02:48:23
2 pub directory jan/02/1970 02:54:47
3 crs226-export.rsc script 357 jan/02/1970 03:46:45
4 console-dump.txt .txt file 16.8KiB may/02/2016 14:53:49
5 DHCP-DNS-work.rsc script 6.1KiB apr/21/2016 22:10:42
6 WAN0-WAN2.rsc script 9.2KiB may/01/2016 11:16:57
7 helden-static-WAN2-plus-route.rsc script 9.6KiB may/01/2016 16:39:51
8 dhcp-server-gateway-via-tp-link.rsc script 13.8KiB may/01/2016 20:48:51
9 apc-dhcp-option-43-dhcp.rsc script 15.6KiB may/02/2016 15:17:02
10 dude dude store may/03/2016 12:25:48
11 udp-67-dhcp file 21.4KiB may/03/2016 16:27:48
12 scripts.rsc script 38.1KiB may/16/2016 08:35:43
13 mikrotik-dns-dhcp.script.rsc.txt .txt file 3070 may/17/2016 07:26:40
14 playground.rsc.txt .txt file 1350 may/17/2016 07:26:37
15 Function.escapeString.rsc.rsc.txt .txt file 1430 may/17/2016 07:26:37
16 Function.stripInvalidHostNameCharactersFromString.rsc.rsc.txt .txt file 1510 may/17/2016 07:26:37
17 Function.padLeftString.rsc.rsc.txt .txt file 1590 may/17/2016 07:26:37
18 Function.varDump.rsc.rsc.txt .txt file 1670 may/17/2016 07:26:37
19 Function.padRightString.rsc.rsc.txt .txt file 1750 may/17/2016 07:26:37
20 Function.endsWithString.rsc.rsc.txt .txt file 1830 may/17/2016 07:26:37
21 Function.startsWithString.rsc.rsc.txt .txt file 1910 may/17/2016 07:26:37
–jeroen
Let me guess… the ones that fail are ‘playground’ and ‘Function.escapeString.rsc’, right?
Yeah… there’s a restriction of 4096 KiB when creating or writing to files. IIRC, uploading and reading such files is still allowed though.