lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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


On Thu, Aug 29, 2013 at 5:04 PM, Ousmane Roland Yonaba <roland.yonaba@gmail.com> wrote:
Hi community,

It is known that one can execute shell commands via Lua's native os.execute, or io.open. 
I am willing to get the output of a specific command. This command is supposed to return an output, but can also fairly err, depending on the user configuration.

The thing is, when we actually input a wrong command in a shell output, it prints an an error message readily, while still running the Lua program. Well, is it possible to somehow shadow that error message ? Catching the output, redirecting it somewhere else, and then display (or not) a custom-made report instead ? If so, can I have some pointers, in terms of code ?

As I am horrible at stating things in simple and few words (I do admire native english-speaking people conciseness), I can come up with an example, if needed.


Best regards,
Roland Y.