[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Shadow shell error messages when running os.execute/io.popen from Lua
- From: Ousmane Roland Yonaba <roland.yonaba@...>
- Date: Fri, 30 Aug 2013 12:54:17 +0000
On Thu, Aug 29, 2013 at 11:35 PM, Pierre-Yves Gérardy <pygy79@gmail.com> wrote:
> You could try something like this (modified from either another lua-l
> post or the Wiki, I don't remember):
>
> function execute(command)
> -- returns success, error code, output.
> local f = io.popen(command..' 2>&1 && echo " $?"')
> local output = f:read"*a"
> local begin, finish, code = output:find" (%d+)\n$"
> output, code = output:sub(1, begin -1), tonumber(code)
> return code == 0 and true or false, code, output
> end
>
> success, code, output = execute"ls -lA"
>
> Both stdout and stderr end up intertwined in the "output" variable.
>
> It is a bit of a hack, but it works. The key lies in this line:
>
> local f = io.popen(file..' 2>&1 && echo " $?"')
>
> which redirects stderr to stdout, and appends the exit code ("$?") to
> the output.
>
> A similar method can be used in Windows. I didn't implement it and I
> don't remember the details, but here's the gist of it.
>
> It can't be done using only the stadard "cmd" shell (the one called by
> io.popen) because the equivalent of "$?" is evaluated before the
> command is run, and it returns the exit code of the previous process.
>
> You have to invoke the PowerShell passing it the command encoded in
> Base 64 (and first pre-process the command to extract the exit code,
> just like in the function above).
>
> -- Pierre-Yves
Thanks so much, Pierre Yves.
Although my computer is running Windows, however, I would not want (as possible)
to rely on PowerShell, as it was included in Windows 7, and thus not available on previous versions of Windows.
But anyway, yay, I learnt a lot from your contribution.
On Fri, 30 Aug 2013 07:11:12 AM, Thijs Schreijer <thijs@thijsschreijer.nl> wrote:
> If you use temporary files for stdout and stderr then this penlight [1] code might also provide an implementation
> [1] https://github.com/stevedonovan/Penlight/blob/master/lua/pl/utils.lua#L221
Ah, Penlight. I quickly took a peek at the code and I think I got the trick.
The script below, taken from Penlight, redirects both stdin and stdout to external temporary files.
Those files need to be deleted manually, as os.tmpname leaves them after the program ends.
local function readfile(fname)
local f = io.open(fname,'r')
local contents = f:read('*a')
f:close()
return contents
end
local function execute(cmd)
local outfile = os.tmpname()
local errfile = os.tmpname()
cmd = cmd .. ' >"'..outfile..'" 2>"'..errfile..'"'
local code = os.execute(cmd)
print('Running: '..cmd)
print('>> Success', code==0, 'Code', code)
print('Read Outfile: ', readfile(outfile))
print('Read Errfile: ', readfile(errfile))
os.remove(outfile)
os.remove(errfile)
end
It works flawlessly. Thanks for the tip, Thijs.
And, well, long live to Steve D. and his Penlight. :)
Regards,
Roland