[HowTo] Labor-Firmware "Inhaus": LUA Konsole

koyaanisqatsi

IPPF-Urgestein
Mitglied seit
24 Jan 2013
Beiträge
14,210
Punkte für Reaktionen
590
Punkte
113
Moinsen


Angeregt von @eisbaerin ...
Ich wollte schon immer mal wissen wozu das gut ist.
...schubs ich mal einen ( klitzekleinen ) Crashkurs an, der aufzeigt wofür die LUA Konsole zu Gebrauchen ist.

Aufruf im Webbrowser: http://fritz.box/?lp=cmd ( Einloggen nicht vergessen ;) )
LUA-Konsole_start.png
Sie ist etwas abgespeckt und nach einigen Rumprobieren eignet sich wirklich nur "return" für eine Ausgabe von Text ( Strings ) und Variablen.
( Normalerweise: print() )

Basics
Das Definieren von Variablen und ihre Ausgabe mittels "return" geht so...
Code:
-- Variablen hello und world mit Inhalt befüllen...
hello="Hello"
world="World"

-- Ausgabe
return hello .. " " .. world .. "!"



Erweitertes Beispiel mit Aufruf von Betriebssystemfunktionen
( Aber das selbe Prinzip ;) )
Code:
-- Variablen d und t mit Inhalt befüllen...
d=os.date("%d.%m.%Y")
t=os.time()
-- os.date() und os.time() = Betriebssystemfunktionen

-- Ausgabe
return d .. " <- Datum -- Epoch -> " .. t
-- Wobei die zwei Punkte als Verkettungsoperatoren dienen
Quelle

Noch Fragen ?
:rolleyes: ( bin gespannt )
 
Zuletzt bearbeitet:
  • Like
Reaktionen: NDiIPP und v!king
Gut :D

Als Nächstes zeig ich euch mal die Kombination von zwei verschiedenen Bibliotheken und vor Allen die Definition und Nutzung des Datentyps "Table".

Beispielanwendung: Lottozahlengenerator ( 6 aus 49 )
Code:
-- Lottozahlengenerator
-- Datentyp = Table ( Array )
math.randomseed(os.time())
lottozahlen = {"Sechs aus Neunundvierzig",math.random(1,49),math.random(1,49),math.random(1,49),math.random(1,49),math.random(1,49),math.random(1,49),"Zusatzzahl: "..math.random(0,9)}
return lottozahlen
Die Bibliothek für die Mathematik: KlickKlack
 
Zuletzt bearbeitet:
Ein kleines Problem hat Dein Lottozahlengenrator: Es kann zweimal dieselbe Zahl zurückgeliefert werden (und die Zusatzzahl liegt zwischen 0 und 9)... ;)
 
Tja, das wäre im nächsten Kapitel: Errorhandling and Flowcontrol
:rolleyes: ( ...wie ungeduldig )

Bis dahin...

Diesmal geben wir nur einzelne Tableelemente aus.
...zum Glück funkioniert die "nächste Zeile" ( \n ) auch in "return"
Code:
-- Lottozahlengenerator
-- Datentyp = Table ( Array )
math.randomseed(os.time())
lottozahlen = {"Sechs aus Neunundvierzig",math.random(1,49),math.random(1,49),math.random(1,49),math.random(1,49),math.random(1,49),math.random(1,49),"Zusatzzahl: "..math.random(0,9)}
return lottozahlen[1]..":\n"..lottozahlen[2].."\n"..lottozahlen[3].."\n"..lottozahlen[4].."\n"..lottozahlen[5].."\n"..lottozahlen[6].."\n"..lottozahlen[7].."\n"..lottozahlen[8]
...das sieht dann auch schon eher nach was aus ;)


@SnoopyDog: Die Zusatzzahl korrigiert, ich spiel dass ja gar nicht :D


Erkenntnisgewinn :)

Es gibt noch eine Methode um Ausgaben mit HTML zu machen: box.out()
Code:
box.out("<pre>Datum/Zeit:</pre> "..os.date().."<pre>Epoch:</pre> "..os.date("%s"))
return 'Schau mal was über "Eingabe" steht.'

...und noch Eine...

Funktionsdefinition

Code:
-- Wir basteln ( definieren ) uns eine Funktion printf()

printf = function(s,...)
return io.write(s:format(...))
end

-- ..und probieren es gleich mal aus...
printf("%s%s",math.pi,"\n")
-- Quelle: http://lua-users.org/wiki/LuaPrintf
( Diese ist mächtiger als es den Anschein hat ;) )

...stay tuned


( Diese ist mächtiger als es den Anschein hat ;) )
Was mein ich denn damit ?

Wir simulieren einen BTX Hack
Code:
-- os.execute() liefert eigentlich nur 0 oder 1 zurück
-- Wird aber io.write("\n") aufgerufen, erscheinen die Ausgaben
-- Wie damals beim CCC und dem BTX Hack

printf = function(s,...)
return io.write(s:format(...))
end

mytable = {}
mytable["ps"] = os.execute("ps")
mytable["df"] = os.execute("df")
mytable["free"] = os.execute("free")
mytable["sip"] = os.execute("showshringbuf sip")
mytable["invite"] = os.execute("showshringbuf invite")

printf("\n")
Ist zwar alles in einer Zeile und gewrapped, aber alles da :D
Das macht einen "telnetd" oder "shellinabox" womöglich überflüssig :cool:

Geschichte des BTX Hacks: Der legendäre Klack-klack-Hack

...next: Shellausgaben ( formatiert ) mit Hilfe der LUA Konsole und des Mediaservers
 
Zuletzt bearbeitet:
Shellausgaben ( formatiert ) mit Hilfe der LUA Konsole und des Mediaservers
( Ausgabe: LAN Geräte und Tickets für gesperrte ( Kindersicherungs ) Profile )
Code:
-- Formatierte Ausgabe eines Shellkommandos mit Hilfe des Mediaservers
-- Im Webbrowser: http://fritz.box:49200/luaout.html
mytable = {}
mytable["htmldocs"] = "/var/media/ftp/"
mytable["html"] = "luaout.html"
mytable["cmd"] = os.execute('echo -ne "<!DOCTYPE html>\n<html style=\'color:black;background-color:silver;\'>\n<head>\n<meta http-equiv=content-type content=\'text/html; charset=utf-8\'/>\n<link rel=\'shortcut icon\' type=\'image/x-icon\' href=\'http://fritz.box/favicon.ico\'/>\n<title>LUA Output</title>\n</head>\n<body>\n<article>\n<pre>" >'..mytable["htmldocs"]..mytable["html"]..'')
mytable["fehler"] = false
mytable["ergebnis"] = "Ergebnis: "
mytable["server"] = "http://fritz.box:49200/"..mytable["html"]

if ( mytable["cmd"] == 0 ) then
 mytable["cmd"] = os.execute('printf "\tGeräte\t\tAktiv\tOnline\tIP\n" >>'..mytable["htmldocs"]..mytable["html"]..'')
else
 return mytable["fehler"]
end

if ( mytable["cmd"] == 0 ) then
 mytable["cmd"] = os.execute('ctlmgr_ctl l landevice "settings/landevice/list(active,online,ip)" >>'..mytable["htmldocs"]..mytable["html"]..'')
else
 return mytable["fehler"]
end

if ( mytable["cmd"] == 0 ) then
 mytable["cmd"] = os.execute('printf "\nTickets:\n" >>'..mytable["htmldocs"]..mytable["html"]..'')
else
 return mytable["fehler"]
end

if ( mytable["cmd"] == 0 ) then
 mytable["cmd"] = os.execute('ctlmgr_ctl r userticket settings/ticket0/id >>'..mytable["htmldocs"]..mytable["html"]..'')
else
 return mytable["fehler"]
end

if ( mytable["cmd"] == 0 ) then
 mytable["cmd"] = os.execute('ctlmgr_ctl r userticket settings/ticket1/id >>'..mytable["htmldocs"]..mytable["html"]..'')
else
 return mytable["fehler"]
end

if ( mytable["cmd"] == 0 ) then
 mytable["cmd"] = os.execute('ctlmgr_ctl r userticket settings/ticket2/id >>'..mytable["htmldocs"]..mytable["html"]..'')
else
 return mytable["fehler"]
end

if ( mytable["cmd"] == 0 ) then
 mytable["cmd"] = os.execute('ctlmgr_ctl r userticket settings/ticket3/id >>'..mytable["htmldocs"]..mytable["html"]..'')
else
 return mytable["fehler"]
end

if ( mytable["cmd"] == 0 ) then
 mytable["cmd"] = os.execute('ctlmgr_ctl r userticket settings/ticket4/id >>'..mytable["htmldocs"]..mytable["html"]..'')
else
 return mytable["fehler"]
end

if ( mytable["cmd"] == 0 ) then
 mytable["cmd"] = os.execute('ctlmgr_ctl r userticket settings/ticket5/id >>'..mytable["htmldocs"]..mytable["html"]..'')
else
 return mytable["fehler"]
end

if ( mytable["cmd"] == 0 ) then
 mytable["cmd"] = os.execute('ctlmgr_ctl r userticket settings/ticket6/id >>'..mytable["htmldocs"]..mytable["html"]..'')
else
 return mytable["fehler"]
end

if ( mytable["cmd"] == 0 ) then
 mytable["cmd"] = os.execute('ctlmgr_ctl r userticket settings/ticket7/id >>'..mytable["htmldocs"]..mytable["html"]..'')
else
 return mytable["fehler"]
end

if ( mytable["cmd"] == 0 ) then
 mytable["cmd"] = os.execute('ctlmgr_ctl r userticket settings/ticket8/id >>'..mytable["htmldocs"]..mytable["html"]..'')
else
 return mytable["fehler"]
end

if ( mytable["cmd"] == 0 ) then
 mytable["cmd"] = os.execute('ctlmgr_ctl r userticket settings/ticket9/id >>'..mytable["htmldocs"]..mytable["html"]..'')
else
 return mytable["fehler"]
end

if ( mytable["cmd"] == 0 ) then
 mytable["cmd"] = os.execute('echo -ne "</pre>\n</article>\n</body>\n</html>" >>'..mytable["htmldocs"]..mytable["html"]..'')
else
 return mytable["fehler"]
end

if ( mytable["cmd"] == 0 ) then
 box.out("<span>",mytable["ergebnis"],"<a href='",mytable["server"],"' target='_blank'>",mytable["html"],"</a></span>")
 return mytable["ergebnis"]..mytable["server"]
else
 return mytable["fehler"]
end

Standardeinstellung des Mediaservers: aktiviert
Webserver aktiv auf HTTP Port: 49200
Die LUA Konsole liefert bei Erfolg die Adresse ( URL ) und einen klickbaren Link auf die erzeugte HTML.
 
Bugbefreiter Lottozahlengenerator
Code:
-- Lottozahlengenerator
-- Diesmal ohne Mehrfachziehung einer gleichen Zahl
zahl={}
for i = 1,49,1 do zahl[i] = i end

math.randomseed(os.time())

for i = 1,6,1 do
 erg=math.random(1,(#zahl))
 box.out("<h4>Ziehung "..i," = ",table.remove(zahl,erg),"</h4>")
end

box.out("<h5>Zusatzzahl"," = ",math.random(0,9),"</h5>")
...nur, wieso funktioniert denn dies besser als der Code der ersten Version ?
 
Zuletzt bearbeitet:
Wie der aufmerksame Leser vielleicht schon gemerkt hat, sind Tables die grosse Stärke vom portugiesischen Mond ( LUA ;) )

Damit können nicht nur sämtliche Datentypen ( function, string, number, bool, table, userdata ) vorgehalten werden, nein, damit gehen sogar Metatables.
OK, ich hab ein Weilchen gebraucht zu kapieren was das denn nun wieder ist, aber genau das bringt Magie ins Table.
Nicht alles klappt damit reibungslos in der LUA-Konsole der Fritz!Box, deswegen hab ich auf einer richtigen Linux-Installation mit LUA 5.3 gelernt :D

Eine Impression...
Zwischenablage01.png
Das Bild ist eigentlich selbsterklärend.
Aber mal der Reihe nach...
1. Eine Funktionssammlung ( koys.lua ) wird mit dofile() nachgeladen
2. Eine Funktion ( koys.mt() ) installiert/assoziiert ein Metatable mit dem Table 'koys'
3. Mit der Funktion k.tshow(getmetatable(koys)) wird das Metatable ausgegeben
Quelle: http://lua-users.org/wiki/MetatableEvents

Hier noch die Funktionen aus koys.lua
Zwischenablage01.png

...stay tuned
 
Zuletzt bearbeitet:
Moins


AVM nutzt ein Table namens "box".
Eine Funktion daraus haben wir hier ja schon benutzt: box.out()
Nun gibt es in "box" auch ein Table namens: glob
...da stehen für die LUA-Konsole relevaten Daten drinne.

Beispiel ( Metatable und die Metamethode: __call )
Code:
setmetatable(box.glob,{
__call=function(t,a)
if ( a ~= nil ) then
for k,v in pairs(a)
do
  box.out('<div>',k,' = ',v,'</div>')
end
else
for k,v in pairs(t)
do
  box.out('<div>',k,' = ',v,'</div>')
end
end
end
})

-- So wird das Table selbst zu einer Funktion
box.glob()

return 'Ein Metatable wird auf ein oder mehrere Tables angewendet'
 
Zuletzt bearbeitet:
Du musst als "seed" ( math.randomseed() ) die Epoch ( os.time() ), also Datum/Zeit der tatsächlichen Ziehung nehmen.
;) ( Aber, wie immer, ohne Gewähr )
 
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.