2017-08-29 50 views
2

我有一个lua REPL,并且希望在HTTPS://URL上运行一个以纯文本形式存储的lua脚本文件。我知道os.execute()可以运行OS命令,所以我们可以使用curl等获取脚本,然后load()。 lua REPL中只有一行可行吗?Oneliner从在线(Gist)加载Lua脚本并在当前上下文中运行

+3

'(loadstring或load)(io.popen(“wget -qO- http://i.imgur.com/91HtaFp.gif”):读取“* a”)()' - 此程序将打印“你好世界“ –

+0

这个程序在做什么并不明显。我发现它运行wget的gif并加载该gif作为代码,并以某种方式神奇地做世界你好吗? – hyiltiz

+0

另外,当我尝试在我的REPL中运行它时,它失败了:输入:1:尝试调用一个零值(字段'popen')。也许我的REPL受限制?它是更大程序的一部分,作为嵌入式模块。 'io.open'和'io.stdout'似乎也能工作。 – hyiltiz

回答

2

注:如果你打算从网络上直接运行的源代码,至少使用https,避免容易MITM攻击。

为了给这个问题的答案,因为叶戈尔可能不会发布它是这样:

(loadstring or load)(io.popen("wget -qO- https://i.imgur.com/91HtaFp.gif"):read"*a")() 

对于为什么这个打印Hello world

loadstring or load是要与不同的Lua版本兼容,因为功能loadstringload在某个时候合并(我相信5.2)。 io.popen在shell中执行它的第一个参数并返回一个文件指针到它的stdout。

从叶戈尔的“GIF”是不是一个真正的GIF(在浏览器中打开此:view-source:https://i.imgur.com/91HtaFp.gif),但包含该文本的纯文本文件:

GIF89a=GIF89a 
print'Hello world' 

基本上是一个GIF与GIF89a=GIF89a开始之后只是为了生成有效的Lua,这意味着您不必使用imgur或gif,您也可以使用原始gist或github。现在

,这是相当不可能的os.execute是在沙箱中时可用io.popen不大,但如果是这样,就可以实现一个班轮使用os.execute(虽然大幅更长)和临时文件

让我们第一次写这一点,因为在单行这将是一个有点复杂:

(function(u,f) 
    -- get a temp file name, Windows prefixes those with a \, so remove that 
    f=f or os.tmpname():gsub('^\\','') 
    -- run curl, make it output into our temp file 
    os.execute(('curl -s "%s" -o "%s"'):format(u,f)) 
    -- load/run temp file 
    loadfile(f)() 
    os.remove(f) 
end)("https://i.imgur.com/91HtaFp.gif"); 

你可以轻松地凝聚到这一条线通过删除注释,制表符和换行符:

(function(u,f)f=f or os.tmpname():gsub('^\\','')os.execute(('curl -s "%s" -o "%s"'):format(u,f))loadfile(f)()os.remove(f)end)("https://i.imgur.com/91HtaFp.gif"); 
+0

但是在沙箱里,这是不可能的? – hyiltiz

+0

@hyiltiz如果沙箱既不允许'os.​​execute'也不允许'io.popen',那么你显然不能走这条路。也许它支持其他选项,比如套接字或者仅仅是它自己的API来打开http连接,但是我们不能告诉你,除非它是公开实现,并且告诉我们它是哪一个,它是 – dualed

+0

@dualed - 为什么是“community wiki”?不要害羞。你做得很好,你的回答非常好。你应该获得赚取的代表点。 –