53

When I do an "os.execute" in Lua, a console quickly pops up, executes the command, then closes down. But is there some way of getting back the console output only using the standard Lua libraries?

Drealmer
  • 5,578
  • 3
  • 30
  • 37

3 Answers3

80

If you have io.popen, then this is what I use:

function os.capture(cmd, raw)
  local f = assert(io.popen(cmd, 'r'))
  local s = assert(f:read('*a'))
  f:close()
  if raw then return s end
  s = string.gsub(s, '^%s+', '')
  s = string.gsub(s, '%s+$', '')
  s = string.gsub(s, '[\n\r]+', ' ')
  return s
end

If you don't have io.popen, then presumably popen(3) is not available on your system, and you're in deep yoghurt. But all unix/mac/windows Lua ports will have io.popen.

(The gsub business strips off leading and trailing spaces and turns newlines into spaces, which is roughly what the shell does with its $(...) syntax.)

Norman Ramsey
  • 198,648
  • 61
  • 360
  • 533
  • 1
    Do you have an example of how to use the above? – starbeamrainbowlabs Oct 20 '15 at 06:51
  • 1
    I used this to get percent power left for some proprietary UPS software `local curPercent = os.capture("sudo pwrstat -status | grep 'Battery Capacity' | cut -d ' ' -f 3", false) --make sure you have rule in /etc/sudoers to run this pwrstat without password (NOPASSWD)` I have the second option of the os.capture function above set to `false` so that it'll strip out the newline you normally get. – Logg Sep 22 '16 at 15:51
  • 1
    What is this `gsub` business about? – mpen Jul 27 '20 at 04:21
  • 1
    @mpen it trims white space from the beginning and end, and replaces carriage return+new line with a single space. – Matthew Leingang Oct 30 '21 at 12:12
29

I think you want this http://pgl.yoyo.org/luai/i/io.popen io.popen. But it's not always compiled in.

Arle Nadja
  • 396
  • 4
  • 8
1

I don't know about Lua specifically but you can generally run a command as:

comd >comd.txt 2>&1

to capture the output and error to the file comd.txt, then use the languages file I/O functions to read it in.

That's how I'd do it if the language itself didn't provide for capturing stanard output and error.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • This is Windows specific but is a method that solved for me. An example of whole command string passed to execute is "cmd.exe /c c:\pathtoit\someprogram.exe -arg1 somefile > c:\temp\out.txt 2>&1". The 2> part was the trick for me. – jdr5ca Jun 29 '14 at 22:44
  • 3
    This is not Windows specific. It will also work in Unix, Linux, BSD, OS X, and many other systems. I'm not the biggest fan of frivolous temporary files, so I don't like this approach, though it technically works. The `2>&1` part redirects standard error (output 2) to standard output (output 1), which was already redirected to comd.txt (`>` is shorthand for `1>`) – Adam Katz Nov 07 '14 at 22:31