64

Is it possible to read the following from the local variable in Lua?

local t = os.execute("echo 'test'")
print(t)

I just want to achieve this: whenever os.execute returns any value, I would like to use it in Lua - for example echo 'test' will output test in the bash command line - is that possible to get the returned value (test in this case) to the Lua local variable?

henriquehbr
  • 1,063
  • 4
  • 20
  • 41
Cyclone
  • 14,839
  • 23
  • 82
  • 114

5 Answers5

118

You can use io.popen() instead. This returns a file handle you can use to read the output of the command. Something like the following may work:

local handle = io.popen(command)
local result = handle:read("*a")
handle:close()

Note that this will include the trailing newline (if any) that the command emits.

Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
  • 1
    Getting this message: `'popen' not supported`. – Cyclone Mar 13 '12 at 00:40
  • @Cyclone: According to the manual, "This function is system dependent and is not available on all platforms". What platform are you trying this on? The only workaround I can think of given the available functions is to use `os.execute()` but redirect standard output to a known temporary file, and then read the temporary file afterwards. – Lily Ballard Mar 13 '12 at 00:41
  • I'm using FreeBSD 8.2. About your second suggestion - could you give me some example of how it should look like? And how about the performace? Its a lot of writing/reading. – Cyclone Mar 13 '12 at 02:48
  • 7
    @Cyclone: Something like `os.execute(command .. " >/tmp/foo")` (where `/tmp/foo` is replaced by an actual somewhat unique path, however you want to calculate it). – Lily Ballard Mar 13 '12 at 03:16
  • Could I do the opposite of what the question asks? Return a Lua value in the os shell. – Unknow0059 Jun 26 '20 at 14:05
  • Trying with `local handle = io.popen([[echo wifiap> \\.\COM78]])` but this is probably not the way how to read back response from COM port. – Sany Oct 16 '20 at 09:23
4
function GetFiles(mask)
   local files = {}
   local tmpfile = '/tmp/stmp.txt'
   os.execute('ls -1 '..mask..' > '..tmpfile)
   local f = io.open(tmpfile)
   if not f then return files end  
   local k = 1
   for line in f:lines() do
      files[k] = line
      k = k + 1
   end
   f:close()
   return files
 end
rhomobi
  • 57
  • 1
  • 2
3

If supported on your system, io.popen is better suited for this use-case than os.execute. The later only returns the exit status not the output.

-- runs command on a sub-process.
local handle = io.popen('cmd')
-- reads command output.
local output = handle:read('*a')
-- replaces any newline with a space
local format = output:gsub('[\n\r]', ' ')

Working example:

local handle = io.popen('date +"%T.%6N"')
local output = handle:read('*a')
local time = output:gsub('[\n\r]', ' ')
handle:close()
print(time .. 'DEBUG: Time recorded when this event happened.')
lh0n42
  • 31
  • 2
-6

Lua's os.capture returns all standard output, thus it will be returned into that variable.

Example:

local result = os.capture("echo hallo")
print(result)

Printing:

hallo
Tunaki
  • 132,869
  • 46
  • 340
  • 423
  • 3
    I don't think this method is part of the `os` module. http://www.lua.org/manual/5.3/manual.html#6.9 – rodvlopes Mar 13 '16 at 18:23
  • 2
    This requires the snippe from [this answer](https://stackoverflow.com/a/326715/1895378) and it uses popen. – HaoZeke Aug 08 '20 at 05:34
-20

Sorry, but this is impossible. If the echo programm exit with success it will return 0. This returncode is what the os.execute() function get and returned too.

if  0 == os.execute("echo 'test'") then 
    local t = "test"
end

This is a way to get what you want, i hope it helps you.

Another Tip for getting the return code of a function is the Lua reference. Lua-Reference/Tutorial