os.rename() / os.remove() / os.time()
Lua's os library includes OS-level file operation functions such as renaming, deleting, and creating temporary files, as well as os.time() for retrieving the current time as a UNIX epoch integer. It is useful when you want to manage files in pure Lua without relying on external commands. Understanding the return value pattern — true on success, nil, message on failure — makes error handling straightforward.
Syntax
-- -----------------------------------------------
-- os.rename() — rename or move a file
-- -----------------------------------------------
-- Returns true on success
-- Returns nil, error message, error code on failure
local ok, err = os.rename("old_filename", "new_filename")
if not ok then
print("Rename failed: " .. err)
end
-- -----------------------------------------------
-- os.remove() — delete a file or empty directory
-- -----------------------------------------------
-- Returns true on success
-- Returns nil, error message, error code on failure
local ok2, err2 = os.remove("filename_to_delete")
if not ok2 then
print("Delete failed: " .. err2)
end
-- -----------------------------------------------
-- os.time() — get UNIX epoch seconds (integer)
-- -----------------------------------------------
-- No argument → returns the current time as epoch seconds
local now = os.time()
print(now) -- e.g. 1711123456
-- Pass a table to convert a specific date/time to epoch seconds
-- Table keys: year, month, day, hour, min, sec
local t = os.time({ year=2024, month=3, day=23, hour=12, min=0, sec=0 })
print(t) -- e.g. 1711188000
-- -----------------------------------------------
-- os.tmpname() — generate a temporary file path
-- -----------------------------------------------
-- Returns a path string for a temporary file provided by the OS
-- You are responsible for creating and deleting the file itself
local tmp = os.tmpname()
print(tmp) -- e.g. /tmp/lua_XXXXXa
-- -----------------------------------------------
-- os.clock() — get CPU time used (seconds)
-- -----------------------------------------------
-- Returns the CPU time used by the process in seconds
local start = os.clock()
-- ... processing ...
local elapsed = os.clock() - start
print(string.format("CPU time: %.4f seconds", elapsed))
Syntax List
| Syntax | Description |
|---|---|
os.rename(old, new) | Renames (or moves) a file or directory from old to new. Returns true on success, or nil, message, code on failure. |
os.remove(path) | Deletes a file or empty directory. Returns true on success, or nil, message, code on failure. |
os.time() | Returns the current time as a UNIX epoch integer. |
os.time(table) | Converts a date/time given as a table (year, month, day, hour, min, sec) to epoch seconds. |
os.date(format, time) | Converts epoch seconds to a formatted string or table. Passing "*t" as format returns a table. |
os.difftime(t2, t1) | Returns the difference (in seconds) between two epoch second values. |
os.tmpname() | Returns a path string for a temporary file. The caller is responsible for creating and deleting the file. |
os.clock() | Returns the CPU time used by the process in seconds. Used to measure execution time. |
Sample Code
jujutsu_log.lua
-- jujutsu_log.lua — sample for os.rename() / os.remove() / os.time()
-- Manages technique logs for Jujutsu Kaisen characters using files
-- -----------------------------------------------
-- Helper function: write to a file
-- -----------------------------------------------
-- Writes text to path. Raises an error if the file cannot be opened
local function write_file(path, text)
local f, err = io.open(path, "w")
if not f then
error("Could not open file: " .. err)
end
f:write(text)
f:close()
end
-- -----------------------------------------------
-- Helper function: wrapper for os.rename()
-- -----------------------------------------------
-- Prints an error message and returns false on failure
local function safe_rename(old_path, new_path)
local ok, err = os.rename(old_path, new_path)
if not ok then
print("[WARN] Rename failed (" .. old_path .. " -> " .. new_path .. "): " .. err)
return false
end
print("Rename succeeded: " .. old_path .. " -> " .. new_path)
return true
end
-- -----------------------------------------------
-- Helper function: wrapper for os.remove()
-- -----------------------------------------------
-- Prints an error message and returns false on failure
local function safe_remove(path)
local ok, err = os.remove(path)
if not ok then
print("[WARN] Delete failed (" .. path .. "): " .. err)
return false
end
print("Delete succeeded: " .. path)
return true
end
-- -----------------------------------------------
-- Data: Jujutsu Kaisen characters
-- -----------------------------------------------
-- Sorcerers from Tokyo Jujutsu High
local sorcerers = {
{ name = "Itadori Yuji", grade = "Special Grade (equivalent)", cursed_technique = "Divergent Fist", domain = "None" },
{ name = "Fushiguro Megumi", grade = "Grade 2", cursed_technique = "Ten Shadows Technique", domain = "Chimera Shadow Garden" },
{ name = "Kugisaki Nobara", grade = "Grade 3", cursed_technique = "Straw Doll Technique", domain = "None" },
{ name = "Gojo Satoru", grade = "Special Grade", cursed_technique = "Limitless", domain = "Infinite Void" },
{ name = "Nanami Kento", grade = "Grade 1", cursed_technique = "Ratio Technique", domain = "None" },
}
-- -----------------------------------------------
-- Get the current timestamp using os.time()
-- -----------------------------------------------
local timestamp = os.time()
local date_str = os.date("%Y-%m-%d %H:%M:%S", timestamp)
print("=== Sorcerer Activity Log Generation Started ===")
print("Timestamp: " .. date_str .. " (epoch: " .. timestamp .. ")")
print("")
-- -----------------------------------------------
-- Step 1: Write to a temporary log file
-- -----------------------------------------------
local tmp_log = "jujutsu_tmp.log"
local final_log = "jujutsu_record.log"
local backup_log = "jujutsu_record.bak"
-- Write the header and each sorcerer's data to tmp_log
local lines = {}
lines[#lines + 1] = "# Sorcerer Activity Log — Generated: " .. date_str .. "\n"
lines[#lines + 1] = string.format("%-24s %-28s %-22s %s\n",
"Name", "Grade", "Cursed Technique", "Domain Expansion")
lines[#lines + 1] = string.rep("-", 90) .. "\n"
for _, s in ipairs(sorcerers) do
lines[#lines + 1] = string.format("%-24s %-28s %-22s %s\n",
s.name, s.grade, s.cursed_technique, s.domain)
end
write_file(tmp_log, table.concat(lines))
print("Temporary file written: " .. tmp_log)
print("")
-- -----------------------------------------------
-- Step 2: Rename existing final_log to backup if it exists
-- -----------------------------------------------
-- os.rename() returns an error if the target does not exist,
-- so use io.open() to check existence before renaming
local f_check = io.open(final_log, "r")
if f_check then
f_check:close()
print("Existing log detected. Renaming to backup...")
safe_rename(final_log, backup_log)
print("")
end
-- -----------------------------------------------
-- Step 3: Rename tmp_log to final_log
-- -----------------------------------------------
safe_rename(tmp_log, final_log)
print("")
-- -----------------------------------------------
-- Step 4: Print the contents of final_log
-- -----------------------------------------------
print("--- Final Log File Contents ---")
local f_read = io.open(final_log, "r")
if f_read then
print(f_read:read("*a"))
f_read:close()
end
-- -----------------------------------------------
-- Step 5: Measure elapsed time using os.time()
-- -----------------------------------------------
-- Generate an epoch value for a specific date and calculate the difference from now
-- A hypothetical date for Itadori's first battle against a cursed spirit
local first_battle = os.time({ year=2018, month=9, day=1, hour=18, min=0, sec=0 })
local elapsed_sec = os.difftime(timestamp, first_battle)
local elapsed_days = math.floor(elapsed_sec / 86400) -- 86400 seconds = 1 day
print(string.format("%d days have passed since the first battle (approx. %.1f years)",
elapsed_days, elapsed_days / 365.0))
print("")
-- -----------------------------------------------
-- Step 6: Delete the backup file
-- -----------------------------------------------
-- Only attempt deletion if backup_log exists
local f_bak = io.open(backup_log, "r")
if f_bak then
f_bak:close()
print("Deleting backup file...")
safe_remove(backup_log)
end
print("")
print("=== Done ===")
The command looks like this:
lua jujutsu_log.lua === Sorcerer Activity Log Generation Started === Timestamp: 2026-03-23 14:05:32 (epoch: 1742731532) Temporary file written: jujutsu_tmp.log Rename succeeded: jujutsu_tmp.log -> jujutsu_record.log --- Final Log File Contents --- # Sorcerer Activity Log — Generated: 2026-03-23 14:05:32 Name Grade Cursed Technique Domain Expansion ------------------------------------------------------------------------------------------ Itadori Yuji Special Grade (equivalent) Divergent Fist None Fushiguro Megumi Grade 2 Ten Shadows Technique Chimera Shadow Garden Kugisaki Nobara Grade 3 Straw Doll Technique None Gojo Satoru Special Grade Limitless Infinite Void Nanami Kento Grade 1 Ratio Technique None 2760 days have passed since the first battle (approx. 7.6 years) === Done ===
Overview
os.rename(old, new) renames or moves a file or empty directory to a new path. os.remove(path) deletes a file or empty directory. Both functions return true on success, or three values — nil, error message, error code — on failure, so you should always check the return value and handle errors accordingly. os.time() returns the current time as a UNIX epoch integer when called with no arguments; passing a table converts a specific date and time to epoch seconds. os.difftime(t2, t1) returns the difference between two epoch values in seconds, and combining it with os.date() makes converting to a human-readable format easy. Because the standard library has no dedicated function to check whether a file exists, the common pattern is to use io.open() for that check beforehand. For reading and writing files, see also io.open() / io.close() and io.lines() / file:read() / file:write().
If you find any errors or copyright issues, please contact us.