Home > Net >  How to write and then read pipe on lua?
How to write and then read pipe on lua?

Time:10-19

local script = [[
            [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
            Invoke-RestMethod https://raw.githubusercontent.com/MyAcc/MyBranch/main/blabla.lua  -Method Get -Headers @{"Authorization" = "Bearer XXXXXXXXXXXXXXXXXXXXXX"}
            
            ]]
        local pipe = io.popen("powershell -command -","w"):write(script)
        local result = pipe:read('*all')
        pipe:close()
        print(result)

I already read on this question How to create two way pipe but i still cant figure it out on how to implement that on my code, i want to read after the pipe write

CodePudding user response:

You can, you just have to specify what to read from the pipe. If you specify '*all' then your program is basically going to wait until the pipe is closed. You should try reading line by line using pipe:read('*line')

CodePudding user response:

You cannot both read and write from a pipe in Lua.
But if the whole input is known before running the process, you can use echo STDIN | command trick.
The solution you linked works for Linux.
Windows requires more complex code:

-- the command to be executed
local your_command = "powershell -command -"

-- the stdin to be passed to the command (the last line must be terminated with newline character)
local your_stdin = [[
   [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
   Invoke-RestMethod https://raw.githubusercontent.com/MyAcc/MyBranch/main/blabla.lua  -Method Get -Headers @{"Authorization" = "Bearer XXXXXXXXXXXXXXXXXXXXXX"}
]]


-- for Linux
local function echo_text_linux(s)
   -- escaping in Linux is easy
   return "echo '"..s:gsub("'", "'\\''").."'"
end

-- for Windows
local function echo_text_windows(s)
   -- some wizardry is required to escape all symbols correctly
   -- (for example, to not allow %PATH% be replaced with the value of the env variable)
   local escaped = { ["("]="^(", [")"]="^)", ["&"]="^&",  ["|"]="^|", ["^"]="^^", [">"]="^>", ["<"]="^<", ["%"]="%^<", ['"']="%^>" }
   local lines = {}
   for line in s:gmatch"(.-)\n" do
      table.insert(lines, "echo("..line:gsub(".", escaped))
   end
   return 'cmd /d/c "for /f "tokens=1-3delims=_" %^< in ("%_"_"")do @('..table.concat(lines, "&")..')"'
end

-- choose you OS here by selecting correct function
local echo_text = echo_text_windows

local function run_command(command, stdin)
   -- returns stdout
   local pipe = io.popen(echo_text(stdin).." | "..command, "r")
   local stdout = pipe:read"*a"
   pipe:close()
   return stdout
end

local your_stdout = run_command(your_command, your_stdin)
print(your_stdout)
  • Related