Home > Net >  How to use return value at Lua, C on Linux?
How to use return value at Lua, C on Linux?

Time:08-19

i've checked following URL: Lua os.execute return value

I've made a program with C which returns 111 or 222. Here is part of my code.

if (stat == NULL)
{
    system("echo \"stat is NULL\"");
    return 111;
}
else
{
    system("echo \"stat is NOT NULL\"");
    return 222;
}

when i run this at Linux like this, ~/c-program; echo $?, it prints

stat is NULL
111

or,

stat is NOT NULL
222

at my terminal.

or like this,

~/c-program
echo $?

it also prints same way like ~/c-program; echo $?

I need to run that program via Lua. Here is part of my lua script.

local foo = io.popen(~/c-program; echo $?)
local bar = foo:read("*a")
foo:close()

if (tonumber(bar) == 111) then
    os.execute("echo 111")
elseif (tonumber(bar) == 222) then
    os.execute("echo 222")
else
    os.execute("echo \"something is wrong\"")
    os.execute("echo "..bar)
end

this prints like this

something is wrong

Even it has a script that prints the value of bar, it does not print. I thought that ``os.execute("echo "..bar)``` syntax is wrong, but it's not.

i tried like this at https://www.lua.org/cgi-bin/demo

local bar = 111

if (tonumber(bar) == 111) then
    print("bar is "..bar)
elseif (tonumber(bar) == 222) then
    print("bar is "..bar)
else
    print("something is wrong")
    print("bar is "..bar)
end

it prints bar is 111. In case bar's value is 333, it also prints something is wrong

So, how should i do to use that c-program's return value as a Lua's variable?

CodePudding user response:

local foo = io.popen(~/c-program; echo $?) looks wrong: popen expects a string, and I have no idea what that unquoted stuff will look like to the Lua parser.

If it did work, it would give "stat is NULL" or "stat is not NULL" followed by the exit code of the C program. It would be tricky to get the number from that, since tonumber will NOT skip past non-number text to find one. It would be simpler to get the exit code directly:

First, skip the echo $? part of the command, so that the shell call will just run the C program and nothing else.

If the Lua code doesn't need the output "stat is NULL" or "stat is not NULL", use just os.execute instead of io.popen.

Documentation for os.execute says

Its first result is true if the command terminated successfully, or fail otherwise. After this first result the function returns a string plus a number, as follows:

  • "exit": the command terminated normally; the following number is the exit status of the command.
  • "signal": the command was terminated by a signal; the following number is the signal that terminated the command.

And documentation for file:close() says

When closing a file handle created with io.popen, file:close returns the same values returned by os.execute.

So you should be able to do any one of

-- Don't need the output text, and allow c-program to print it.
local ok, how, code = os.execute("~/c-program")

-- OR, Don't need the output text, and make sure it's not printed anywhere.
local ok, how, code = os.execute("~/c-program >/dev/null")

-- OR, Need the output text within Lua
local foo = io.popen("~/c-program")
do_stuff(foo)
local ok, how, code = foo:close()

followed by

if how == "exit" then
    if code == 111 then
        print("Got 111")
    elseif code == 222 then
        print("Got 222")
    else
        print("Exited with code " .. code)
    end
elseif how == "signal" then
    print("Stopped by signal " .. code)
else
    print("What happened?")
end

CodePudding user response:

A Program can exit in two different ways...

  1. An exit code like 0 (On Linux that means: OK - No Error)
  2. Textoutput...
    a) Normal: stdout
    b) Error: stderr

With Lua you can produce an errorless exit code wit: os.exit(0)
And an Error with: os.exit(1)

Also, like in other languages, it is common to use echo or/and print to produce dynamic output i.e. like XML/HTML/CSS/Javascript code.
Example for returning error code 1 in Lua Standalone:

$ lua
Lua 5.4.4  Copyright (C) 1994-2022 Lua.org, PUC-Rio
> rc = 1
> if rc ~= 0 then
>> io.output(io.stderr)
>> io.write('ERROR - EXIT\n')
>> os.exit(rc)
>> end
ERROR - EXIT
$ echo $?
1
$

...so in case of an error stderr is used to put out the errortext and the exit code of 1 can be used as a condition for further processing (in bash/shellscript).

Something to read about exit command and code...
https://linuxize.com/post/bash-exit/

Now lets check what os.execute() is returning...

> os.execute('echo "Hello World"')
Hello World
true    exit    0

os.execute() is returning three values and you want the third one.

You can grab it then by defining three locals with os.execute() and use only the last one...

local one, two, three = os.execute('~/c-program')
print(three)
return three
  • Related