lua-users home
lua-l archive

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


Hi Alexander,

You're not alone! I write a lot of shell scripts and once in a while I get fed up by the arcane syntax required (e.g. double escaping of regular expression patterns and other such nonsense). So I switch to Lua, use my shell module for a few days but eventually return to the UNIX shell because it enables a quick and dirty approach to scripting that just doesn't work in a proper language like Lua :-(. I've attached my shell.lua module anyway, it contains some untested code but should serve to illustrate how I use Lua as a shell scripting language.

 - Peter Odding
shell = {}

setmetatable(shell, {
 __index = function(self, program)
  return function(...)
   return shell.execute(program, ...) == 0
  end
 end,
})

function shell.dialog(message)
 return shell.execute('zenity', '--info', '--text', message) == 0
end

function shell.escape(...)
 local command = type(...) == 'table' and ... or { ... }
 for i, s in ipairs(command) do
  s = (tostring(s) or ''):gsub('"', '\\"')
  if s:find '[^A-Za-z0-9_."/-]' then
   s = '"' .. s .. '"'
  elseif s == '' then
   s = '""'
  end
  command[i] = s
 end
 return table.concat(command, ' ')
end

function shell.execute(...)
 return os.execute(shell.escape(...))
end

function shell.read(...)
 local handle = assert(io.popen(shell.escape(...) .. ' 2>&1'))
 local output = {}
 for line in handle:lines() do
  table.insert(output, line)
 end
 assert(handle:close())
 return table.concat(output, '\n')
end

function shell.lines(...)
 local handle = assert(io.popen(shell.escape(...) .. ' 2>&1'))
 return handle:lines()
end

function shell.write(command, string)
 local handle = assert(io.popen(command, 'w'))
 assert(handle:write(string))
 assert(handle:close())
end

function shell.getcwd()
 local pipe = assert(io.popen('pwd'))
 local path = assert(pipe:read('*l'))
 pipe:close()
 return path
end

local logger

function shell.log(message, ...)
 message = message:format(...)
 logger = logger ~= false and os.execute(shell.escape('logger', message)) == 0
 io.stderr:write(message, '\n')
end

return shell