2017-08-29 111 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」?不要害羞。你做得很好,你的回答非常好。你應該獲得賺取的代表點。 –