I'm trying to kill a process using Lua: my bash script "run.sh" prints a string each 2 seconds and up to now I was able to catch real-time the output but I need to quit that process too whenever i send a command to my telegram bot
Here is my actual code:
local bot, extension = require("lua-bot-api").configure('myBotToken')
local function test()
local pipe = io.popen'/home/ubuntu/workspace/LmBot/run.sh'
repeat
local c = pipe:read("*line")
if c then
io.write(c)
io.flush()
bot.sendMessage(msg.from.id,c,"Markdown")
end
until not c
pipe:close()
end
extension.onTextReceive = function(msg)
local matches = {msg.text:match('^/(.+)$')}
if(matches[1]=='start')then
test()
end
end
extension.run()
As you can see, when I send command /start it runs my bash script (is that a child process? am I right?) and sends me back a message with the output parsed by lines in real time.
I now need to be able to kill the process started before, are there any ways using lua?
Thank you all in advance :)
Related
I would like to know if you could help me with a Roblox script. From chat admin, when I say !kill user I want to the user to be killed. This is all I could do:
target = "Woozy"
Player.Chatted:connect(function(cht)
if cht:match("!kill") then
Kill(target)
end
First, you can't use ! prefix (maybe),
Second, you need to add local before target, Third, do Kill(target) code really kills you?, Fourth, you need to add end) for end of your function.
Try insert ModuleChat into Chat library then copy this code to the script
local AdminCommands = require(1163352238)
local Utilities = AdminCommands.Utilities
function killPlayer(commandData)
game.Players.LocalPlayer.Character.Humanoid.Health = 0
end
AdminCommands:BindCommand({"kill"}, killPlayer, 1, "Kill the user")
return AdminCommands.Run
Then type /kill. Your command should ready now.
I got it from Roblox Developer Article. You can check that here
You can unbind the command too, using this code
AdminCommands:UnbindCommand({"kill"})
I need to call a command(in a sinatra or rails app) like this:
`command sub`
Some log will be outputed when the command is executing.
I want to see the log displaying continuously in the process.
But I just can get the log string after it's done with:
result = `command sub`
So, is there a way to implement this?
On windows i have the best experience with IO.popen
Here is a sample
require 'logger'
$log = Logger.new( "#{__FILE__}.log", 'monthly' )
#here comes the full command line, here it is a java program
command = %Q{java -jar getscreen.jar #{$userid} #{$password}}
$log.debug command
STDOUT.sync = true
begin
# Note the somewhat strange 2> syntax. This denotes the file descriptor to pipe to a file. By convention, 0 is stdin, 1 is stdout, 2 is stderr.
IO.popen(command+" 2>&1") do |pipe|
pipe.sync = true
while str = pipe.gets #for every line the external program returns
#do somerthing with the capturted line
end
end
rescue => e
$log.error "#{__LINE__}:#{e}"
$log.error e.backtrace
end
There's six ways to do it, but the way you're using isn't the correct one because it waits for the process the return.
Pick one from here:
http://tech.natemurray.com/2007/03/ruby-shell-commands.html
I would use IO#popen3 if I was you.
I want to execute background processes concurrently from a lua script
like :
a = io.popen("deploy.exp" .. ip1):read("*a")
b = io.popen("deploy.exp" .. ip2):read("*a")
where a,b are continually running processes. When i do this as above, b will only run when a is finished. And the deploy.exp script is an expect script which used to ssh few servers, and execute some commands. Then I need to fetch some text from a and b. Any idea on this? I tryed with the ExtensionProposal API. When I tried that I get one error messages that say: "* glibc detected free(): invalid next size (fast): 0x08aa2300 ** abort".
The part code is
for k,v in pairs(single) do
command = k .. " 1 " .. table.concat(v, " ")
local out = io.pipe()
local pro = assert(os.spawn("./spaw.exp " .. command,{
stdout = out,
}))
if not proc then error("Failed to aprogrinate! "..tostring(err)) end
print(string.rep("#", 50))
local exitcode = proc:wait()
end
Has anybody any experience (or advice / where we should look) with this? or give me a sample? Thanks
BTW: I tried the luaposix, but I can't find any sample by posix.fork(). Does anyone could share one? TKS
posix.fork() is part of the luaposix library, which can be installed via luarocks. It works in much the same way as fork(3); it creates an copy of the parent process, and both of them will execute everything after the call to fork(). The return value of fork() is 0 in the child process, otherwise it's the PID of the child that was just spawned. Here's a contrived example:
local posix = require "posix"
local pid = posix.fork()
if pid == 0 then
-- this is the child process
print(posix.getpid('pid') .. ": child process")
else
-- this is the parent process
print(posix.getpid('pid') .. ": parent process")
-- wait for the child process to finish
posix.wait(pid)
end
-- both processes get here
print(posix.getpid('pid') .. ": quitting")
This should output something like the following:
$ lua fork.lua
27219: parent process
27220: child process
27220: quitting
27219: quitting
You might want to try Lua Lanes (or from here), which is a portable threading library for Lua.
I need to use Lua to run a binary program that may write something in its stdout and also returns a status code (also known as "exit status").
I searched the web and couldn't find something that does what I need. However I found out that in Lua:
os.execute() returns the status code
io.popen() returns a file handler that can be used to read process output
However I need both. Writing a wrapper function that runs both functions behind the scene is not an option because of process overhead and possibly changes in result on consecutive runs. I need to write a function like this:
function run(binpath)
...
return output,exitcode
end
Does anyone has an idea how this problem can be solved?
PS. the target system rung Linux.
With Lua 5.2 I can do the following and it works
-- This will open the file
local file = io.popen('dmesg')
-- This will read all of the output, as always
local output = file:read('*all')
-- This will get a table with some return stuff
-- rc[1] will be true, false or nil
-- rc[3] will be the signal
local rc = {file:close()}
I hope this helps!
I can't use Lua 5.2, I use this helper function.
function execute_command(command)
local tmpfile = '/tmp/lua_execute_tmp_file'
local exit = os.execute(command .. ' > ' .. tmpfile .. ' 2> ' .. tmpfile .. '.err')
local stdout_file = io.open(tmpfile)
local stdout = stdout_file:read("*all")
local stderr_file = io.open(tmpfile .. '.err')
local stderr = stderr_file:read("*all")
stdout_file:close()
stderr_file:close()
return exit, stdout, stderr
end
This is how I do it.
local process = io.popen('command; echo $?') -- echo return code of last run command
local lastline
for line in process:lines() do
lastline = line
end
print(lastline) -- the return code is the last line of output
If the last line has fixed length you can read it directly using file:seek("end", -offset), offset should be the length of the last line in bytes.
This functionality is provided in C by pclose.
Upon successful return, pclose() shall return the termination status
of the command language interpreter.
The interpreter returns the termination status of its child.
But Lua doesn't do this right (io.close always returns true). I haven't dug into these threads but some people are complaining about this brain damage.
http://lua-users.org/lists/lua-l/2004-05/msg00005.html
http://lua-users.org/lists/lua-l/2011-02/msg00387.html
If you're running this code on Win32 or in a POSIX environment, you could try this Lua extension: http://code.google.com/p/lua-ex-api/
Alternatively, you could write a small shell script (assuming bash or similar is available) that:
executes the correct executable, capturing the exit code into a shell variable,
prints a newline and terminal character/string onto standard out
prints the shell variables value (the exit code) onto standard out
Then, capture all the output of io.popen and parse backward.
Full disclosure: I'm not a Lua developer.
yes , your are right that os.execute() has returns and it's very simple if you understand how to run your command with and with out lua
you also may want to know how many variables it returns , and it might take a while , but i think you can try
local a, b, c, d, e=os.execute(-what ever your command is-)
for my example a is an first returned argument , b is the second returned argument , and etc.. i think i answered your question right, based off of what you are asking.
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.