Run script instructions from external source in Lua - lua

Ok, I'm wanting to know if there's a way of running scripts from an external source with Lua. Be it another file in .txt format or from pastebin, what have you, and run the code and wait for said code to finish, and then continue on with the rest of the function. I'm not quite sure at all about how it'd work, but this is basically the idea I'm going by and isn't actual code.
function runStuff()
print("checking for stuff")
run.script(derp.txt)
wait for script
if run.script == finished
continue program
elseif nil
print("looks like this script sucks.")
end
end
runStuff()
And for example what "derp.txt" contains is:
function lookFile()
if herp.txt exists then
rename herp.txt to herp.lua
else
nil
end
end
lookFile()
I'm still new to Lua so I'm coding like a moron here, but you get my picture hopefully. I'm working on a project that'll act like an installer package for repositories based from pastebin or anywhere else that'll supply raw format outputs of lua scripts and I'm going to use that idea for it to call on scripts to run externally. So when I supply a "First Time Run" version of the program, it'll call out to a lua script that'll call to another lua script and install that script, then close.
This is for minecraft, mind you. ComputerCraft made me take interest in Lua, but anyway, hopefully you got the gist of what I'm trying to figure out. Hopefully that's doable and if not, I'll just have to figure something else out.

To load and execute a Lua code fragment you can use something like this:
local http = require("socket.http")
local response, err = http.request("url to some Lua code")
if not response then error(err) end
local f, err = (loadstring or load)(response)
if not f then error(err) end
print("done with "..response)
-- make sure you read on (in)security implications of running remote code
-- f() -- call the function based on the remote code
You probably need to use sandboxing.

Related

How to set io.output() back to default output file?

I am learning how work with files in Lua, and I came across a problem.
I know that:
io.output() allows me to specify the file that I will write output to.
The io.write() function simply gets a number of string arguments and writes them to the current output file.
io.close() then closes the file I am reading or writing on.
I first set io.output() to "myNewFile.txt" then I did io.write("Hello World!").
io.output("myNewFile.txt")
io.write("Hello World!")
This part worked well and myNewFile.txt got Hello World written to it.
Then I wrote io.close() to close the myNewFile.txt.
After that, I wrote io.write("Hello World!"), but I got an error:
C:\\Program Files\\lua\\lua54.exe: ...OneDrive\\Documents\\learning lua\\steve's teacher\\main.lua:9: default output file is closed stack traceback: \[C\]: in function 'io.write' ...OneDrive\\Documents\\learning lua\\steve's teacher\\main.lua:9: in main chunk \[C\]: in ?
I wanted io.write("Hello World!") to write Hello World in the terminal. I know can use print() but print() function adds extra characters like \n and things like that.
So my question is, how do I write Hello World in the terminal using io.write("Hello World!") in this situation?
I tried to search this error up on Google, but there weren't any results. I also tried joining many Discord servers, but I didn't get a proper response. I am a new developer to Lua so this all is really confusing to me.
After io.close() do a io.output(io.stdout) to set it back.
The clean way
local oldout = io.output() -- without argument returns actual output
io.output("file") -- set to a filename
-- do file operations here
-- use io.flush() where it is necessary
io.close() -- close file also do a flush()
io.output(oldout) -- set back to oldout ( normally io.stdout )
-- changing io.output() back should also close() and flush() the "file"
-- But better doublecheck this when using userdata without experience

Lua io.popen freezing after a while of reading a log file

I'm attempting to constantly read and parse a log file (Minecraft log file) by using io.popen in tandem with Ubuntu's tail command so that I can send some messages upon certain events.
Now, I have mostly everything working here, except one small issue. After a while of reading, the entire program just freezes.
Here is the relevant code:
-- Open the tail command, return a file handle for it.
local pop = io.popen(config.listen_command)
-- Simply read a single line, I've pulled this into its own
-- function so that if this ever needs changing I can do so
-- easily.
local function get_line()
logger:log(4, "READ LINE")
return pop:read("*l")
end
-- For each line in the log file, check if it matches any
-- of a list of patterns, return the matches and the
-- pattern information if so.
local function match_line()
local line = get_line()
logger:log(4, "Line: %s", line)
-- This all works, and I've tested that it's not freezing
-- here. I've just included it for completion of the call
-- -stack.
for event_type, data in pairs(config.message_patterns) do
for event_name, pattern in pairs(data) do
local matches = {line:match(pattern)}
if matches[1] then
return event_type, event_name, matches
end
end
end
end
-- The main loop, simply read a line and send a message
-- if there was a match.
logger:log(4, "Main loop begin.")
while true do
local event_type, event_name, matches = match_line()
-- ...
-- The rest of the code here is not relevant.
config.listen_command = "tail -F --lines=1 latest.log"
The issue is in the get_line function. After a while of reading the log file, it completely freezes on the pop:read("*l"). It prints the READ LINE message, but never prints the Line: <whatever data here> line.
This is a really strange issue that I've been getting really confused about. I've tried swapping to different distributions of Lua (Luvit, LuaJIT, Lua) and a very large amount of debugging, changing small things, rerunning, ... But I cannot think of anything that'd be causing this.
Perhaps there's something small I've missed.
So my question here is this: Why is pop:read("*l") freezing, even though more data is being outputted to the logfile? Is there a way to fix this? Perhaps to detect if the next read will freeze indefinitely, so I can try closing the popen'ed file and re-open it (or to preferably stop it happening altogether?)

Lua script pc to sleep

So i got a new keyboard wit hG-keys. (hotkeys) And i'm not familiar with lua...
So could anybody give me a very simple command that sets my pc to sleep? please?
if gkey == 7 and mkey == 1 then
if event == "G_PRESSED" then
end
end
gkeys
so gkey is the key that is pressed, and mkey is the set it uses. i can have up to 54 differint scripts/macro's.
I want to know what i have to put after the last 'then' so my pc goes to sleep.
thx ahead
edit 1:
got this:
if gkey == 1 and mkey == 3 then
if event == "G_PRESSED" then
execute("rundll32.exe powrprof.dll,SetSuspendState 0,1,0");
end
end
error is: [string "LuaVM"]:40: attempt to call global 'execute'(a nil value)
and with os.execute i get this error:
[string "LuaVM"]:40: attempt to index global 'os'(a nil value)
final answer: not possible with gseries keyboard. use a shortcut
Given the reference to G-keys and the G_PRESSED in your code snippet, I am assuming you have one of the Logitech G-Series keyboards. These keyboards can be programmed so that certain keys run Lua scripts using a custom Lua 5.1 interpreter. The documentation is included with Logitech's Gaming Software program.
According to the documentation, only some of the standard library functions are supported: the string, math and table are available. However, the io, os and debug libraries are not available.
So I doubt you'll be able to make your PC go to sleep.
EDIT in response to OP edit: the Lua library you have access to has the os library removed, so you're probably not going to be able to make your computer sleep directly.
There might be an indirect way to do this by writing something that listens for debugging messages, which you can generate with OutputDebugMessage. There's a Team Speak plugin that does this. But it's probably beyond your programming ability right now and far beyond the scope of a Stackoverflow post to explain.
You can use os.execute to run an executable from Lua.
If you google "Windows sleep command line" you'll get another Stackoverflow post which shows two ways of doing it. One requires that you turn hibernation off, the other requires that you download an additional utility (PsShutdown).
Assuming you've downloaded PsShutdown and put it somewhere in your PATH, then you can use the following to sleep the computer:
os.execute('psshutdown -d -t 0')

Lua check if a file is open or not

I'm trying to script a lua file to check if a certain file is open. Then I want it to close that file if it is open. I know how to check if the file exist but I need to know how to check if the file is open, meaning the file is running.
Lua, like C, C++, and pretty much every other language, can only close files that it opens itself. You cannot close files open by other people (not with standard Lua calls); this would be incredibly rude.
So you can't test to see if a file is opened by someone else. Nor can you close their file. There may be system API calls you could make to do this, but you would have to give Lua scripts access to those APIs yourself. Lua's standard libraries can't do this.
Sounds like you want to check which if any programs have a given file open.
first thing that comes to mind is parsing the output of lsof on linux.
fd = io.popen("lsof path/to/my/file")
fileopened = (#fd:read("a*") > 0)
Kind of a hacky way to do it, but it works:
processname = "process_name_here.exe"
filedata = io.popen("tasklist /NH /FO CSV /FI \"IMAGENAME eq "..processname.."\"")
output = filedata:read()
filedata:close()
if output ~= "INFO: No tasks are running which match the specified criteria." then
-- Program is running. Close the program
os.execute("taskkill -im "..processname)
else
-- Program is not running
end
Just make sure to replace "process_name_here.exe" with the process name that shows up in task manager
Alternatively you can just use this to close it without checking if it was actually running:
os.execute("taskkill -im process_name_here.exe")

Reboot a System through Lua Script

I need to reboot System through a Lua Script.
I need to write some string before the Reboot happens and need to write a string in a Lua
script once the Reboot is done.
Example :
print("Before Reboot System")
Reboot the System through Lua script
print("After Reboot System")
How would I accomplish this?
You can use os.execute to issue system commands. For Windows, it's shutdown -r, for Posix systems it's just reboot. Your Lua code will therefore look like this:
Be aware that part of the reboot command is stopping active programs, like your Lua script. That means that any data stored in RAM will be lost. You need to write any data you want to keep to disk, using, for instance, table serialization.
Unfortunately, without more knowledge of your environment, I can't tell you how to call the script again. You could be able to append a call to your script to the end of ~/.bashrc or similar.
Make sure that loading this data and starting at a point after you call your reboot function is the first thing that you do when you come back! You don't want to get stuck in an endless reboot loop where the first thing your computer does when it turns on is to turn itself off. Something like this should work:
local function is_rebooted()
-- Presence of file indicates reboot status
if io.open("Rebooted.txt", "r") then
os.remove("Rebooted.txt")
return true
else
return false
end
end
local function reboot_system()
local f = assert(io.open("Rebooted.txt", "w"))
f:write("Restarted! Call On_Reboot()")
-- Do something to make sure the script is called upon reboot here
-- First line of package.config is directory separator
-- Assume that '\' means it's Windows
local is_windows = string.find(_G.package.config:sub(1,1), "\\")
if is_windows then
os.execute("shutdown -r");
else
os.execute("reboot")
end
end
local function before_reboot()
print("Before Reboot System")
reboot_system()
end
local function after_reboot()
print("After Reboot System")
end
-- Execution begins here !
if not is_rebooted() then
before_reboot()
else
after_reboot()
end
(Warning - untested code. I didn't feel like rebooting. :)
There is no way to do what you are asking in Lua. You may be able to do this using os.execute depending on your system and set up but Lua's libraries only include what is possible in the standard c libraries which does not include operating system specific functionality like restart.

Resources