0

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?

Popsicle
  • 61
  • 8
  • 2
    You are reading the entire output using `*a`. That will include newlines. You only want the number, not the entire output. Since the number is the exit code, can't you use `os.execute` which simply returns the exit code? – Luatic Aug 18 '22 at 08:29
  • 2
    Don't you need to put the command in double-quotes? – the busybee Aug 18 '22 at 10:11
  • The C program could just use `puts("stat is NULL")` rather than using `system` and the shell and `echo`. In Lua, you should probably just use `print` rather than `os.execute("echo ...")`, unless the `print` function has been redefined to go somewhere else. `echo` is mostly useful for programming in the shell languages `sh`, `bash`, etc. – aschepler Aug 18 '22 at 19:12
  • i just forgot to add double-quotes only at this question. Thanks for letting me know – Popsicle Aug 19 '22 at 06:25

2 Answers2

1

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
koyaanisqatsi
  • 2,585
  • 2
  • 8
  • 15
1

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
aschepler
  • 70,891
  • 9
  • 107
  • 161
  • Using `local ok, how, code = os.execute("~/c-program")`, and printing with `print(ok, how, code)`, shows `28416 nill nill`(if c-program returns 111), or `56832 nill nill`(if c-program returns 222). i thought my c-program was the problem, but when i just execute at my console with `~/c-program`, and if i type `echo $?`, it returns `111` or `222` well. any more things that i need to check? – Popsicle Aug 19 '22 at 02:45
  • 1
    @Popsicle What version of Lua? Apparently the return specification of `os.execute` changed between Lua 5.1 and 5.2. The docs for 5.1 just say the one returned value is system-dependent, but it appears you got the `exitcode*256 + signal` value some tools use: `56832/256 == 222` – aschepler Aug 19 '22 at 16:50
  • So, my version of Lua is 5.1. that's why it keeps returning like 28416. `local foo = os.execute("~/c-program")`, `local bar = foo/256`, `print(bar)` will print `111` or `222`. That helped me. – Popsicle Aug 22 '22 at 03:02