我正在尝试创建一个在后台运行 shell的程序,并将用户命令发送给它以便执行并返回结果.这是代码: --note: this runs on windows but I assume replacing "cmd" with "sh" it can run on linux as wellexe,err=io.po
--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()调用.执行循环也表现得很奇怪(有时候我必须按几次输入才能使userinput = io.read(“* line”)工作.
我用google搜索文件: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... 1Lua仅依赖于ANSI C功能.因此io.popen使用
popen(3)
功能.引用它的手册:
Since a pipe is by definition unidirectional, the type argument may specify only reading or writing, not both; the resulting stream is correspondingly read-only or write-only.
您尝试通过将输出重定向到文件并同时打开该文件并在执行命令后从中读取来尝试解决此限制.但是,在这种情况下,您可能会遇到输出缓冲问题 – 我认为这正是您所遇到的问题.
您可以尝试使用Lua Ex API(wiki page here),而不是尝试解决io.popen问题,它提供了另一种生成API的过程,并允许您执行以下操作:
-- popen2(), from http://lua-users.org/wiki/ExtensionProposal function popen2(...) local in_rd, in_wr = io.pipe() local out_rd, out_wr = io.pipe() local proc, err = os.spawn{stdin = in_rd, stdout = out_wr, ...} in_rd:close(); out_wr:close() if not proc then in_wr:close(); out_rd:close() return proc, err end return proc, out_rd, in_wr end -- usage: local p, i, o = assert(popen2("wc", "-w")) o:write("Hello world"); o:close() print(i:read"*l"); i:close() p:wait()