zipfs(n)
β¨ zipfs β¨
okay bestie, sit down, hydrate, because zipfs(n) is a whole vibe. this is the zipfs Commands manual page and it's about to teach you how to mount and work with ZIP files within Tcl. π¦
πΈ NAME πΈ
zipfs β Mount and work with ZIP files within Tcl π
π SYNOPSIS π
zipfs canonical ?mountpoint? filename
zipfs exists filename
zipfs find directoryName
zipfs info filename
zipfs list ?(-glob|-regexp)? ?pattern?
zipfs lmkimg outfile inlist ?password? ?infile?
zipfs lmkzip outfile inlist ?password?
zipfs mkimg outfile indir ?strip? ?password? ?infile?
zipfs mkkey password
zipfs mkzip outfile indir ?strip? ?password?
zipfs mount ?zipfile? ?mountpoint? ?password?
zipfs mountdata data mountpoint
zipfs root
zipfs unmount mountpoint
π DESCRIPTION π
The zipfs command gives Tcl the ability to mount the contents of a ZIP archive file as a virtual file system. Tcl's ZIP archive support is limited to basic features and options, so like, don't come in expecting the full deluxe spa package, bestie.
Supported storage methods include only STORE and DEFLATE, with optional simple encryption. That encryption is enough to prevent casual inspection of the contents, but it is not able to prevent access by even a moderately determined attacker. Strong encryption, multi-part archives, platform metadata, zip64 formats and other compression methods like bzip2 are not supported. periodt. π
Files within mounted archives can be written to, but new files or directories cannot be created. Also, modifications to files are limited to the mounted archive in memory and are not persisted to disk. so don't close the app and expect your edits to still be there, because they will not be. π
Paths in mounted archives are case-sensitive on all platforms. all of them. every single one. iykyk.
π«Ά THE COMMANDS π«Ά
zipfs canonical ?mountpoint? filename
This takes the name of a file, filename, and produces where it would be mapped into a zipfs mount as its result. If you pass mountpoint, it says within which mount the mapping will be done; if you omit it, the main root of the zipfs system is used.
zipfs exists filename
Returns 1 if the given filename exists in the mounted zipfs, and 0 if it does not. short, sweet, iconic. β¨
zipfs find directoryName
Returns the list of paths under directory directoryName, which need not be within a zipfs mounted archive. The paths are prefixed with directoryName. This command is also used by the zipfs mkzip and zipfs mkimg commands.
zipfs info file
Returns information about the given file in the mounted zipfs. That information consists of:
- the name of the ZIP archive file that contains the file,
- the size of the file after decompressions,
- the compressed size of the file, and
- the offset of the compressed data in the ZIP archive file.
As a special case, querying the mount point gives the start of the zip data as the offset in (4), which can be used to truncate the zip information from an executable. Querying an ancestor of a mount point will raise an error.
zipfs list ?(-glob|-regexp)? ?pattern?
If pattern is not specified, the command returns a list of files across all zipfs mounted archives. If pattern is specified, only those paths matching the pattern are returned.
By default, or with the -glob option, the pattern is treated as a glob pattern and matching is done as described for the string match command. Alternatively, the -regexp option may be used to specify the matching pattern as a regular expression.
The file names are returned in arbitrary order (so no, you can't count on them being sorted, bestie). Note that path separators are treated as ordinary characters in the matching β thus forward slashes should be used as path separators in the pattern. The returned paths only include those actually in the archive and do not include intermediate directories in mount paths.
zipfs mount
zipfs mount mountpoint
zipfs mount zipfile mountpoint ?password?
The zipfs mount command mounts ZIP archives as Tcl virtual file systems and returns information about current mounts. it's giving three-forms-in-a-trenchcoat. π§
- With no arguments, the command returns a dictionary mapping mount points to the path of the corresponding ZIP archive.
- In the single argument form, the command returns the file path of the ZIP archive mounted at the specified mount point.
- In the third form, the command mounts the ZIP archive zipfile as a Tcl virtual filesystem at mountpoint. After this command executes, files contained in zipfile will appear to Tcl to be regular files at the mount point. If mountpoint is specified as an empty string, it is defaulted to the
[zipfs root]. The command returns the normalized mount point path.
If not under the zipfs file system root, mountpoint is normalized with respect to it. For example, a mount point passed as either mt or /mt would be normalized to //zipfs:/mt (given that zipfs root returns //zipfs:/). An error is raised if the mount point includes a drive or UNC volume.
NB: because the current working directory is a concept maintained by the operating system, usingcdinto a mounted archive will only work in the current process, and then not entirely consistently. For example, if a shared library uses direct access to the OS rather than going through Tcl's filesystem API, it will not see the current directory as being inside the mount, and it will not be able to access the files inside the mount. so like, vibe check yourcds, fr fr. π
zipfs mountdata data mountpoint
Mounts the ZIP archive content data as a Tcl virtual filesystem at mountpoint.
zipfs root
Returns a constant string which indicates the mount point for zipfs volumes for the current platform. User should not rely on the mount point being the same constant string for all platforms. π
zipfs unmount mountpoint
Unmounts a previously mounted ZIP archive mounted to mountpoint. The command will fail with an error exception if there are any files within the mounted archive that are open.
π¦ ZIP CREATION COMMANDS π¦
This package also provides several commands to aid the creation of ZIP archives as Tcl applications. crafting era. π
zipfs mkzip outfile indir ?strip? ?password?
Creates a ZIP archive file named outfile from the contents of the input directory indir (contained regular files only), with optional ZIP password password. While processing the files below indir, the optional file name prefix given in strip is stripped off the beginning of the respective file name if non-empty. When stripping, it is common to remove either the whole source directory name or the name of its parent directory.
Caution: the choice of the indir parameter (less the optional stripped prefix) determines the later root name of the archive's content. so choose wisely, bestie. π
zipfs mkimg outfile indir ?strip? ?password? ?infile?
Creates an image (potentially a new executable file) similar to zipfs mkzip; see that command for a description of most parameters to this command, as they behave identically here. If outfile exists, it will be silently overwritten. not me finding that out the hard way. π
If the infile parameter is specified, this file is prepended in front of the ZIP archive; otherwise the file returned by info nameofexecutable (i.e., the executable file of the running process, typically wish or tclsh) is used. If the password parameter is not the empty string, an obfuscated version of that password (see zipfs mkkey) is placed between the image and ZIP chunks of the output file and the contents of the ZIP chunk are protected with that password. If the starting image has a ZIP archive already attached to it, it is removed from the copy in outfile before the new ZIP archive is added.
If there is a file, main.tcl, in the root directory of the resulting archive and the image file that the archive is attached to is a tclsh (or wish) instance (true by default, but depends on your configuration), then the resulting image is an executable that will source the script in that main.tcl after mounting the ZIP archive, and will exit once that script has been executed. main character energy honestly. π
Note:tclshandwishcan be built using either dynamic binding or static binding of the core implementation libraries. With a dynamic binding, the base applicationTcl_Librarycontents are attached to thelibtclandlibtkshared library, respectively. With a static binding, theTcl_Librarycontents, etc., are attached to the application,tclshorwish. When usingmkimgwith a statically builttclsh, it is the user's responsibility to preserve the attached archive by first extracting it to a temporary location, and then add whatever additional files desired, before creating and attaching the new archive to the new application.
zipfs mkkey password
Given the clear text password argument, an obfuscated string version is returned with the same format used in the zipfs mkimg command.
zipfs lmkimg outfile inlist ?password? ?infile?
This command is like zipfs mkimg, but instead of an input directory, inlist must be a Tcl list where the odd elements are the names of files to be copied into the archive in the image, and the even elements are their respective names within that archive.
zipfs lmkzip outfile inlist ?password?
This command is like zipfs mkzip, but instead of an input directory, inlist must be a Tcl list where the odd elements are the names of files to be copied into the archive, and the even elements are their respective names within that archive.
β οΈ NOTE β οΈ
The current syntax for certain subcommands using multiple optional parameters might change in the future to support an ?-option value? pattern instead. Therefore, the current syntax should not be considered stable. so don't get too attached, bestie. π¦
π§ EXAMPLES π§
Okay bestie, this is the part where it all clicks. Four little scenarios, each one cuter than the last. Let's go. π
β¨ Example 1: mount a ZIP as an app directory and run code from it
So the vibe here is: you've got a ZIP, you want to treat it like a folder, source stuff out of it, and then yeet it away when you're done. Iconic. Here's the whole thing:
set zip myApp.zip
set base [file join [zipfs root] myApp]
zipfs mount $zip $base
# $base now has the contents of myApp.zip
source [file join $base app.tcl]
# use the contents, load libraries from it, etc...
zipfs unmount $base
See how $base is literally just [file join [zipfs root] myApp]? So it lives under the zipfs root, and after the zipfs mount it has the contents of myApp.zip. Then you source your app.tcl out of it, load libraries, whatever your heart desires, and when you're done you zipfs unmount $base. Clean. No mess. Periodt. π
πΈ Example 2: make a ZIP from a directory
Let's say you already have a directory full of stuff and you want to zip it up. Watch this:
set sourceDirectory [file normalize myApp]
set targetZip myApp.zip
zipfs mkzip $targetZip $sourceDirectory $sourceDirectory
Not me pointing out that the source directory is passed twice β but bestie, that's the whole trick. Giving it twice is how you strip the exterior directory name from each filename inside the archive. It's giving "same input, different job". π¦
Also yes, [file normalize myApp] first, because absolute paths are the moment. β¨
π Example 3: encryption, babes
You can lock a ZIP down with a password β once when you build it and again when you mount it. Two password moments, one secure archive:
set zip myApp.zip
set sourceDir [file normalize myApp]
set password "hunter2"
set base [file join [zipfs root] myApp]
# Create with password
zipfs mkzip $targetZip $sourceDir $sourceDir $password
# Mount with password
zipfs mount $zip $base $password
hunter2 is doing a lot of heavy lifting here as the example password, but sure, we support her. π
π Example 4: build a whole executable by appending the ZIP to tclsh
This one is main character energy. You take the tclsh you were called from, glue a ZIP archive onto the end of it, and write the result out as myApp.bin. Boom: an executable application. π₯
And here's the cute bit β when you make an executable image with a password, the password gets stored inside the executable in a shrouded form. So your app can still read files out of the embedded ZIP archive, but a casual snooper can't just read the password off it. π
set appDir [file normalize myApp]
set img "myApp.bin"
set password "hunter2"
# Create some simple content to define a basic application
file mkdir $appDir
set f [open $appDir/main.tcl w]
puts $f {
puts "Hi. This is [info script]"
}
close $f
# Create the executable application
zipfs mkimg $img $appDir $appDir $password
# remove the now obsolete temporary appDir folder
file delete -force $appDir
# Launch the executable, printing its output to stdout
exec $img >@stdout
# prints the following line assuming [zipfs root] returns "//zipfs:/":
# Hi. This is //zipfs:/app/main.tcl
Note how the app directory gets passed twice to zipfs mkimg too β same energy as the mkzip trick. Then you file delete -force the temporary folder because it's obsolete now, and you exec $img >@stdout to launch it. The output is literally:
Hi. This is //zipfs:/app/main.tcl
assuming [zipfs root] returns //zipfs:/. Slay. π«Ά
π SEE ALSO π
Your lil reading list, bestie β go be nosy:
π KEYWORDS π
compress, filesystem, zip
And that's the whole page, fr fr. This was the zipfs(n) man page, coming at you from Zipfs version 1.0 (the date field on this one is justβ¦ blank, no cap, we're timeless π). Go forth and mount things. Byeee πβ¨π
π¦ where this page comes from
- alpine 3.23: tcl9-doc 9.0.3-r0 Β· TCL
- alpine 3.24: tcl9-doc 9.0.3-r2 Β· TCL
- fedora 43: tcl-doc 1:9.0.2-1.fc43 Β· TCL AND GPL-3.0-or-later WITH Bison-exception-2.2 AND BSD-3-Clause
- fedora 44: tcl-doc 1:9.0.2-1.fc44 Β· TCL AND GPL-3.0-or-later WITH Bison-exception-2.2 AND BSD-3-Clause
- nixos 26.05: tcl 9.0.3
- nixpkgs unstable: tcl 9.1.0
- Copyright (c) 2015 Jan Nijtmans <jan.nijtmans@gmail.com>
- Copyright (c) 2015 Christian Werner <chw@ch-werner.de>
- Copyright (c) 2015 Sean Woods <yoda@etoyoc.com>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms