交互式 popen() Lua 调用
我正在尝试创建一个在后台运行 shell 的程序,并向其发送用户命令以执行并返回结果。这是代码:
--note: this runs on windows but I assume replacing "cmd" with "sh" it can run on linux as well
exe,err=io.popen("cmd > stdout.txt 2> stderr.txt");
if not exe then
print("Could not run command. Error: "..err)
return
else
print("Command run successfully... ready!")
end
stdout,err=io.open("stdout.txt","r")
if not stdout then print("Could not open stdout: "..err) return end
stderr,err=io.open("stderr.txt","r")
if not stdout then print("Could not open stderr: "..err) return end
function execute(str)
exe:write(str)
return stdout:read("*all") or stderr:read("*all") or "nil"
end
repeat
print("COMMAND: ")
userinput=io.read("*line")
print("You entered: '"..userinput.."'")
if userinput=="" then print "Empty line! Exiting program..." break end
print("Result: "..execute(userinput))
until true
print "Closing..."
execute("exit")
print "1"
exe:close()
print "2"
stdout:close()
print "3"
stderr:close()
print "Finished!"
问题:退出程序时,它挂在 exe:close()
调用上。执行循环的行为也很奇怪(有时我必须按几次 Enter 键才能 userinput=io.read("*line")
工作。
我用 google 搜索了一下 file:close() 是否也适用文件句柄是 io.popen() 的结果,但没有找到任何内容,但该调用并没有失败,换句话说,程序的输出如下:
Command run successfully... ready!
COMMAND:
dir
dir
You entered: 'dirdir'
Result: Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\lua>
C:\lua>
C:\lua>
Closing...
1
I'm trying to create a program that runs a shell on the background and sends user commands to it for execution and return the result. This is the code:
--note: this runs on windows but I assume replacing "cmd" with "sh" it can run on linux as well
exe,err=io.popen("cmd > stdout.txt 2> stderr.txt");
if not exe then
print("Could not run command. Error: "..err)
return
else
print("Command run successfully... ready!")
end
stdout,err=io.open("stdout.txt","r")
if not stdout then print("Could not open stdout: "..err) return end
stderr,err=io.open("stderr.txt","r")
if not stdout then print("Could not open stderr: "..err) return end
function execute(str)
exe:write(str)
return stdout:read("*all") or stderr:read("*all") or "nil"
end
repeat
print("COMMAND: ")
userinput=io.read("*line")
print("You entered: '"..userinput.."'")
if userinput=="" then print "Empty line! Exiting program..." break end
print("Result: "..execute(userinput))
until true
print "Closing..."
execute("exit")
print "1"
exe:close()
print "2"
stdout:close()
print "3"
stderr:close()
print "Finished!"
Problem: when exiting the program, it hangs on exe:close()
call. The execution loop behaves weird too (sometimes I have to press enter several times for userinput=io.read("*line")
to work.
I googled to see if file:close() also works on the file handle that is the result of io.popen() but didn't find anything. But that call doesn't fail. It just hangs up. In other words the output of the program is like this:
Command run successfully... ready!
COMMAND:
dir
dir
You entered: 'dirdir'
Result: Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\lua>
C:\lua>
C:\lua>
Closing...
1
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Lua 仅依赖于 ANSI C 功能。因此 io.popen 使用
popen(3)
功能。引用它的手册:您尝试通过将输出重定向到文件并在执行命令后同时打开该文件并从中读取来解决此限制。但是,在这种情况下,您可能会遇到输出缓冲问题 - 我认为这就是您所遇到的问题。
您可以尝试使用 Lua Ex API,而不是尝试解决
io.popen
(wiki 页面),它提供了替代的进程生成 API,并允许您执行以下操作:Lua only depends on ANSI C features. Therefore
io.popen
uses thepopen(3)
function. Quoting from it's manual:You attempt to solve this limitation by redirecting the output to a file and simultaneously open that file and read from it after executing a command. However, in this case you may run into problems with output buffering - I think this is what you are experiencing.
Instead of trying to work around
io.popen
, you may try out the Lua Ex API (wiki page here), which provides an alternative process spawning API and allows you to do things like this: