lua-users home
lua-l archive

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

On 2/3/2017 1:14 PM, Sean Conner wrote:
It was thus said that the Great Russell Haley once stated:
On Fri, Feb 3, 2017 at 1:16 AM, Scott Morgan <> wrote:
On 02/03/2017 07:34 AM, Russell Haley wrote:
But the question was what is the argument against the approach
described. ‎ It always has seemed to me that Lua goes to great length
to search relative paths and entirely negates to look in the
application path for no reason whatsoever. It was one of the most
confusing things when I first started looking at Lua.

Lua does use the EXE path in Windows, but under *nix systems things
aren't so simple. There's no guarantee that the path to the executable
exists and no clear way to determine it even if it does[0] (some hacky,
platform dependant ways, but nothing clean).
[snip here]

For scripts I plan to drop somewhere on $PATH and use as a general tool, I usually use the handy function require_here() from Penlight. That and the handy pl.lapp module seem to be part of nearly any tool I write that is expected to be used as anything other than a one-off solution to a problem.

require_here() operates by assuming that it is invoked from a Lua script that itself was executable. On Unix-like systems, it would begin with "#!/usr/bin/env lua" or similar. On Windows, I simply bind *.lua files to my preferred lua.exe using the assoc and ftype commands in the usual way.

On Windows, the result is that arg[-1] names lua.exe, arg[0] has a fully qualified path to the script file, and the rest of arg[1] .. arg[#arg] is the usual command line arguments.

On *nix, the details will depend on the processing of #! lines, and potentially on the behavior of /usr/bin/env if that is included. While the full story of #! is rich with history and quirky details, in modern systems the behavior is pretty stable. In practice, the interpreter is invoked with a fully qualified name of the script. I can't find a promise to that effect, but testing on an older Ubuntu and an Amazon Linux instance is consistent. See [1] for the full history, and a nice table of what to expect to happen tested on a range of *nix platforms.


For testing, I have /usr/bin/lua as the system's Lua 5.1.4, but later versions should behave the same. Two files in ~/bin act as probes, and are both the same trivial Lua script differing only in the shebang lines, and marked executable. ~/bin is in $PATH.

$ cat bin/tpath
print(arg[-1], arg[0], arg[1])
$ tpath hi
/usr/bin/lua     /home/ross/bin/tpath    hi
$ cat bin/tepath
#!/usr/bin/env lua
print(arg[-1], arg[0], arg[1])
$ tepath hi
lua     /home/ross/bin/tpath    hi

Aside from the name of my home directory, the output on the AWS EC2 instance running Amazon Linux was identical. I don't happen to have a true Unix system at hand, but the chart at the link above tends to imply that OpenBSD, NetBSD and FreeBSD will get the same answer.

So it certainly is true that in general a process on Unix cannot depend on argv[0] to contain a fully qualified path. But it appears that the shebang interpreter invocation is special and provides a fully qualified name of the script. And that allows modules to be stored next to the script that needs them.

Ross Berteig                     
Cheshire Engineering Corp. 
+1 626 303 1602