PKG-LUA-SCRIPT(5)
β¨ PKG-LUA-SCRIPT(5) β¨
okay so bestie, welcome to the lua scripts page of the File Formats Manual π
this is literally the whole lore on the lua scripts that get run by pkg(8), and we're gonna get into all of it. no skipping, no skimming, we're doing this properly π«Ά
πΈ DESCRIPTION πΈ
so pkg(8) runs scripts at specific phases of whatever process it's doing, right? and the phases are, in order of the vibes:
pre-installβ runs before the files get installed onto the system.post-installβ runs after the files are installed onto the system.pre-deinstallβ runs before the files get removed from the system.post-deinstallβ runs after the files are removed from the system.
a package can hold multiple scripts per phase, and every single one of them gets run inside its own lua VM (yes, each one gets its own little main-character bubble π«§).
now β the upgrade case is special and honestly kind of iconic. when it's an upgrade, the scripts run in this exact order:
- new
pre-install - old
pre-deinstall - replace binaries
- new
post-install
and one thing that is not a vibe to forget: lua scripts are always run after shell scripts (of the same phase). always. periodt. π
π¦ API π¦
all the regular lua APIs are available to you, EXCEPT for these changes. so listen up, because these are the rules π₯
π the modified ones
io.open()β has been modified so it only opens files relatively to therootdirif one was specified by the-rargument passed topkg(8).os.remove()β has been modified so it only removes files relatively to therootdirif one was specified by the-rargument passed topkg(8).os.rename()β has been modified so it only renames files relatively to therootdirif one was specified by the-rargument passed topkg(8).os.execute()β has been disabled. like, gone. πos.exit()β has been disabled too. also gone. π
π the variables (they come pre-defined for any lua script)
pkg_nameβ the name of the package.pkg_prefixβ thePREFIXdefined within the package at build time.pkg_rootdirβ represents the root directory where the package will be installed, as specified by the-rarguments passed topkg(8).pkg_metalogβ a String containing the path to amtree(5)METALOGfile where package file metadata (e.g., ownership, mode) should be recorded. this is typically used when installing packages as a non-root user. if noMETALOGis configured, this variable is unset and is equal tonil.pkg_upgradeβ a Boolean that informs the scripts whether or not it's running in the context of an upgrade.argβ okay this one's fun β¨ when the first line of a Lua script starts with-- args:followed by a space-separated list of tokens, those tokens get parsed and made available in the globalargtable. this lets you pass arguments to Lua scripts β but it should not be used by regular scripts. it's used internally for deferred triggers. iykyk π«Ά
π the added functions
out pkg.prefixed_path(in)β prependspkg_prefixtoinif needed, and returns it asout.pkg.print_msg(msg)β sends messages to the user that will be shown at the end of thepkg(8)process.pkg.filecmp(file1, file2)β compares 2 files. returns0if the files are identical,1if the files are different, and>1if an error occurred.pkg.metalog_copy(source, destination)β will create an entry in the "metalog" if one has been defined, which will clone the metadata from the source and use it for a new entry for the destination path.pkg.copy(source, destination)β copies a file preserving its attributes. returns-1if an error occurred.st pkg.stat(file)β returns an object tablestwith the following fields:type,size,uid,gid.pkg.symlink(source, destination)β creates a symbolic linkdestinationpointing atsource.pkg.exec(arguments)β will execute the commandarguments, expected in the following form:{command, arg1, arg2, arg3, ...}. the command inherits the parent's standard output and standard error.stdout, stderr, exitcode pkg.exec_capture(arguments)β will execute the commandarguments, expected in the same form aspkg.exec(), capturing its standard output and standard error separately. returns three values:stdout(string containing the captured standard output),stderr(string containing the captured standard error), andexitcode(integer exit status of the command). if the command cannot be started, the first two return values arenilandexitcodecontains the error number.res pkg.readdir(path)β will return anipairwith the list of elements contained in the directory; the special directory.and..are filtered out.
π SEE ALSO π
the whole extended fam, go say hi π
pkg_create(3), pkg_printf(3), pkg_repo_create(3), pkg_repos(3), pkg-keywords(5), pkg-repository(5), pkg-script(5), pkg-triggers(5), pkg.conf(5), pkg(8), pkg-add(8), pkg-alias(8), pkg-annotate(8), pkg-audit(8), pkg-autoremove(8), pkg-check(8), pkg-clean(8), pkg-config(8), pkg-create(8), pkg-delete(8), pkg-fetch(8), pkg-help(8), pkg-info(8), pkg-install(8), pkg-key(8), pkg-lock(8), pkg-plugins(8), pkg-query(8), pkg-register(8), pkg-repo(8), pkg-repositories(8), pkg-rquery(8), pkg-search(8), pkg-set(8), pkg-shell(8), pkg-shlib(8), pkg-ssh(8), pkg-stats(8), pkg-triggers(8), pkg-unregister(8), pkg-update(8), pkg-updating(8), pkg-upgrade(8), pkg-version(8), pkg-which(8)
and that's the whole page bestie, you ate that π this lil masterpiece comes courtesy of Debian, dated April 14, 2026 β slay, go write some scripts π
π¦ where this page comes from
- nixos 26.05: pkg 2.7.5
- nixpkgs unstable: pkg 2.7.5
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms