lua-users home
lua-l archive

Re: io.popen of unknown program succeeds

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


It was thus said that the Great Dirk Laurie once stated:
> 2013年12月28日 Philipp Janda <siffiejoe@gmx.net>:
> 
> > But you can find out (in Lua 5.2) by calling the `close` method on the
> > returned file pointer:
> >
> > > print( io.popen( "no_such_program" ):close() )
> > sh: 1: no_such_program: not found
> > nil exit 127
> > > print( io.popen( "false" ):close() )
> > nil exit 1
> > > print( io.popen( "true" ):close() )
> > true exit 0
> 
> So one could use this instead of io.popen?
> 
> function popen(prog,mode)
> local cond,msg,code = io.popen(prog,mode):close()
> if code==127 then error("'"..prog.."' not found") end
> return io.popen(prog,mode)
> end
 No, much better to check for the existance of the program first:
function popen(program,mode)
 local function exists(name)
 local function check(file)
 local f = io.open(file,"r")
 if f ~= nil then
 f:close()
 return true
 else
 return false
 end
 end
 -- -------------------------------------------------------------------
 -- if given a relative or absolute path, just check the name. No need
 -- to adapt this code for Windows---it'll work as is, as Windows will
 -- also support '/' for directory separators, and it also supports '.'
 -- for the current directory.
 -- -------------------------------------------------------------------
 if name:match("^%./") or name:match("^/") then
 return check(name)
 end
 -- -------------------------------------------------------------------
 -- now check the PATH. If PATH isn't defined, just use an empty string
 -- to avoid some messy logic otherwise.
 -- -------------------------------------------------------------------
 local path = os.getenv("PATH") or ""
 for segment in path:gmatch("([^:]+):?") do
 local file = segment .. "/" .. name
 if check(file) then
 return true
 end
 end
 return false
 end
 local file = program:match("^(%S+)")
 if not exists(file) then
 error('"' .. program .. '" not found')
 end
 return io.popen(program,mode)
end
 But this fails to check if the resulting file is executable (although, if
it's in the PATH, it probably is), and program names with embedded spaces
are problematic. Perhaps if you gave popen() three parameters, the first
being the program, the second being the rest of the command line, and the
final one being the mode would work around the space problem ... 
 -spc (It's always the little details ... )

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