lua-users home
lua-l archive

Re: io.popen: reading both stdout AND stderr

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


Hi!
Am 15.08.2013 15:57 schröbte Lorenzo Donati:
[...]
BTW. If Lua team doesn't deem it useful enough to enhance popen in this
sense, IMO this should be added at least to lfs
On a related note, although a robust workhorse, I find lfs a bit
lacking. I'd really like it to be a little more feature complete.
Maybe you are looking at the wrong library. What about lua-apr[1][2] (also available as a rock[3])?
 [1]: https://github.com/xolox/lua-apr/
 [2]: http://peterodding.com/code/lua/apr/
 [3]: http://luarocks.org/repositories/rocks/#lua-apr
lua-apr is still for Lua 5.1 only, but I have a quick-and-dirty patch for Lua 5.2 support, if you are interested ...
Features I miss from lfs (which should be easy to bind to already
existing APIs in the host OS):
* mkdir cannot create directories recursively ( mkdir "a/b/c" gives an
error if "a" doesn't exist, whereas I'd like to have a flag to tell it
"do make all the intermediate dirs")
 apr.dir_make_recursive(path [, permissions]) → status
* File copy operations.
 apr.file_copy(source, target [, permissions]) → status
 apr.file_append(source, target [, permissions]) → status
 apr.file_link(source, target) → status
* Pathname existance checking and
canonalization/normalization/resolution (e.g. lfs.exists
"/foo/bar/a/b/../../c" would return "/foo/bar/c" if this file exists, or
nil otherwise)
 apr.filepath_root(path [, option, ...]) → root, path
 apr.filepath_parent(path [, option, ...]) → parent, filename
 apr.filepath_name(path [, split]) → filename [, extension]
 apr.filepath_merge(root, path [, option, ...]) → merged
etc...
* lfs.dir iterator should not return ".." and "." as directories.
Especially ".." is dangerous when building recursive functions on top of
lfs.dir: you could by mistake recurse upwards (I'm always wrapping
lfs.dir to remove ".." and ".", but this inconvenient and error prone -
I don't know you, but I never used lfs.dir output directly). At least
this behaviour should be documented.
Other operations that are not strictly file-system operations, but IMO
too much connected to them:
* lfs.setenv (to pair os.getenv)
 apr.env_set(name, value) → status
 apr.env_delete(name) → status
* lfs.popen (as said above)
* lfs.execute having a richer API than os.execute (e.g. see wxWidgets
wxExecute) and allowing sync/async execution
 apr.proc_create(program) → process
 apr.proc_detach(daemonize) → status
 process:user_set(username [, password]) → status
 process:cmdtype_set(type) → status
 process:dir_set(path) → status
 process:io_set(stdin, stdout, stderr) → status
 process:exec([args]) → status
 process:wait(how) → done [, why, code]
 process:kill(how) → status
etc....
Regarding your enhanced popen, this is as far as I got:
 local apr = require( "apr" )
 local proc = assert( apr.proc_create( "./xxx.sh" ) )
 assert( proc:cmdtype_set( "program" ) )
 assert( proc:io_set( 'none', 'parent-block', 'parent-block' ) )
 assert( proc:exec{} )
 local out = proc:out_get()
 local err = proc:err_get()
 print( out:read() )
 print( err:read() )
 local done, why, code = assert( proc:wait( true ) )
 if why == "exit" then
 print( "exit status:", code )
 else
 print( "killed by signal:", code )
 end
The problem (which lfs would face as well) is multiplexing the io of stdout and stderr so that no process is blocked and no output lost ...
I acknowledge that many of the above can be built on top of lfs, but
sometimes it is tricky and anyway not as efficient as wrapping existing
OS APIs.
Cheers.
-- Lorenzo
Philipp

AltStyle によって変換されたページ (->オリジナル) /