#!/usr/bin/luaThe preceding code produces the following output:
sf =string.format
for k, v in ipairs(arg) do
print(sf("k=>%s<, v=>%s<", k, v))
end
slitt@mydesk:~$ ./test.lua one two three fourThere's no getopt() or getopt_long(), but you can either incorporate the posix module or just roll your own getopt() or getopt_long() substitute.
k=>1<, v=>one<
k=>2<, v=>two<
k=>3<, v=>three<
k=>4<, v=>four<
slitt@mydesk:~$
#!/usr/bin/luaThe preceding code produces the following output:
local user = os.getenv("USER")
print(user)
slitt@mydesk:~$ ./test.luaThe one improvement I'd like to see is a table containing all the environent variables so I can iterate through them. If you need that capability, you need to use your operating system's env command or else use Lua's posix module.
slitt
slitt@mydesk:~$
#!/usr/bin/luaYeah, I know, I know, this has a race condition between the time you check for the file's existance and the time you create it. This is a very short time, but yeah, it's a possible race condition or security problem. When using the code on an extremely hard hit server exposed to the public, you're probably best off with the Posix module or making a C module. C module construction is discussed at http://www.troubleshooters.com/codecorn/lua/lua_lua_calls_c.htm.
function open_temp_file(template)
local handle
local fname
assert(string.match(template, "@@@"),
"ERROR open_temp_file: template must contain \"%%%\".")
while true do
fname = string.gsub(template, "@@@", tostring(math.random(10000000,99999999)))
handle = io.open(fname, "r")
if not handle then
handle = io.open(fname, "w")
break
end
io.close(handle)
io.write(".") -- Shows collision, comment out except for diagnostics
end
return handle, fname
end
local handle, fname = open_temp_file("/tmp/xample@@@.jnk")
handle:write(fname .."<->")
handle:write(tostring(os.time()).."\n")
io.close(handle)
#!/usr/bin/luaThe preceding code produces the following output:
require "lfs"
sf = string.format
--### FOR THE NEXT TWO LINES,
--### USE ANY EXISTING DIR AND FILE
--### FOR WHICH YOU HAVE READ RIGHTS
--### AND EXEC RIGHTS ON THE DIRECTORY
existingfile = "junk.jnk" -- THIS FILE MUST ALREADY EXIST!!!
existingdir = "junk" -- THIS DIRECTORY MUST ALREADY EXIST!!!
local attribs = lfs.attributes(existingfile)
for k, v in pairs(attribs) do
print(sf("%s=>%s",k,v))
end
print("======================")
attribs = lfs.attributes(existingdir)
for k, v in pairs(attribs) do
print(sf("%s=>%s",k,v))
end
slitt@mydesk:~$ ./test.luaI leave it as an exercise to recurse directories. Suffice it to say that lfs.attributes().mode indicates whether it's a directory or not.
dev=>2072
change=>1295302296
access=>1295821604
rdev=>0
nlink=>1
blksize=>4096
uid=>503
blocks=>8
gid=>503
ino=>2827232
mode=>file
modification=>1295302296
size=>1938
======================
dev=>2072
change=>1295591507
access=>1295591511
rdev=>0
nlink=>23
blksize=>4096
uid=>503
blocks=>8
gid=>503
ino=>2842637
mode=>directory
modification=>1295591507
size=>4096
slitt@mydesk:~$
#!/usr/bin/luaThe preceding code first iterated through all the elements of the returned table, and then prints a detail of the time. The iteration is an important feature for debugging -- if you do something wrong in printing the date you simply comment out the date and then investigate the information that's really being returned and fix your program accordingly. The preceding code prints out the following:
sf = string.format
local today = os.time()
local datetable = os.date("*t", today)
print()
for k, v in pairs(datetable) do
print(sf("%s=%s", k, tostring(v)))
end
wdays = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"}
print(sf("\n%d seconds since epoch, %s, %d/%d/%d at %02d/%02d/%02d.",
today,
wdays[datetable.wday],
datetable.month,
datetable.day,
datetable.year,
datetable.hour,
datetable.min,
datetable.sec
))
slitt@mydesk:~$ ./test.luaInstead of passing "*t" to os.date(), you can also pass a format string to have it return whatever kind of formatted date you'd like. Here's an example:
hour=16
min=22
wday=1
day=23
month=1
year=2011
sec=37
yday=23
isdst=false
1295817757 seconds since epoch, Sunday, 1/23/2011 at 16/22/37.
slitt@mydesk:~$
#!/usr/bin/luaThe preceding code, much shorter than the one with format "*t", printed basically the same thing without the table iteration:
sf = string.format
local today = os.time()
io.write(tostring(today))
print(os.date(" seconds since epoch, %A, %x at %X"))
slitt@mydesk:~$ ./test.luaPersonally I don't like the two digit year for %x -- we paid dearly for that kind of thinking eleven short years ago. But I'll be safely in my grave before it's an issue again, and it's just a print representation -- obviously Lua keeps a 4 digit representation of years, good until 9999. :-)
1295818399 seconds since epoch, Sunday, 01/23/11 at 16:33:19
slitt@mydesk:~$
interval = os.time() - fewdays * 24*60*60What my research hasn't uncovered is more sophisticated date arithmetic like "the first of the month" or "six months from now" or "two years ago". My research hasn't uncovered anything dealing with leap years or the differing number of days in the month, or the picket fence errors that crop up. Those features wouldn't be difficult to build yourself, but they appear not to come with the standard library.
#!/usr/bin/luaThe preceding code outputs the following:
function backticks_table(cmd)
local tab = {}
local pipe = assert(io.popen(cmd),
"backticks_table(" .. cmd .. ") failed.")
local line = pipe:read("*line")
while line do
table.insert(tab, line)
line = pipe:read("*line")
end
return tab
end
function backticks_string(cmd)
local string
local pipe = assert(io.popen(cmd),
"backticks_string(" .. cmd .. ") failed.")
local line = pipe:read("*all")
return line
end
print("=== Testing backticks_string ===")
print(backticks_string("ping -c2 www.troubleshooters.com"))
print("=== Testing backticks_table ===")
for k, v in ipairs(backticks_table("ping -c2 www.troubleshooters.com"), k) do
print(v)
end
slitt@mydesk:~$ ./test.luaSo they both work perfectly.
=== Testing backticks_string ===
PING troubleshooters.com (69.89.18.20) 56(84) bytes of data.
64 bytes from box20.bluehost.com (69.89.18.20): icmp_seq=1 ttl=47 time=92.9 ms
64 bytes from box20.bluehost.com (69.89.18.20): icmp_seq=2 ttl=47 time=93.7 ms
--- troubleshooters.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 92.912/93.309/93.706/0.397 ms
=== Testing backticks_table ===
PING troubleshooters.com (69.89.18.20) 56(84) bytes of data.
64 bytes from box20.bluehost.com (69.89.18.20): icmp_seq=1 ttl=47 time=92.9 ms
64 bytes from box20.bluehost.com (69.89.18.20): icmp_seq=2 ttl=47 time=93.8 ms
--- troubleshooters.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 92.979/93.408/93.838/0.527 ms
slitt@mydesk:~$
[ Troubleshooters.com| Code Corner | Email Steve Litt ]
Copyright
(C) 2011 by Steve Litt --Legal