file(3tcl)
okay so bestie, pull up a chair πͺ because we're reading file(3tcl) from the Tcl Built-In Commands collection, and honestly? this page is a whole personality. it's THE command for messing with file names and file attributes, and it is lowkey carrying the entire filesystem on its back π
π NAME π
file β manipulate file names and attributes β¨
π¦ SYNOPSIS π¦
file option name ?arg arg ...?
π DESCRIPTION π
okay so this command does a bunch of different operations on a file's name or its attributes, depending on the vibe you're going for. the name argument is, in most cases, just the name of a file. the option argument is the one that tells Tcl what you actually want to do with that file name.
not me being helpful: any unique abbreviation for option is acceptable. so if you're feeling lazy, abbreviate away, bestie π«Ά
the valid options are, in order, and yes we're doing all of them:
file atime name ?time?β returns a decimal string giving the time at which filenamewas last accessed. iftimeis specified, it's an access time to set for the file.
the time is measured in the standard POSIX fashion, as seconds from a fixed starting time (often January 1, 1970). if the file does not exist, or its access time can't be queried or set, then an error is generated. on Windows, FAT file systems do not support access time. on zipfs file systems, access time is mapped to the modification time. periodt. π
file attributes nameβ form one (see below).file attributes name ?option?β form two.file attributes name ?option value option value...?β form three.
this subcommand returns or sets platform-specific values associated with a file. the first form returns a list of the platform-specific options and their values. the second form returns the value for the given option. the third form sets one or more of the values.
the values are as follows, and yes there's a lot, we're going platform by platform like the icon we are π
On Unix:
-groupgets or sets the group name for the file. a group id can be given to the command, but it returns a group name.-ownergets or sets the user name of the owner of the file. the command returns the owner name, but the numerical id can be passed when setting the owner.-permissionsretrieves or sets a file's access permissions, using octal notation by default. this option also provides limited support for setting permissions using the symbolic notation accepted by thechmodcommand, following the form[ugo]?[[+-=][rwxst],[...]]. multiple permission specifications may be given, separated by commas. e.g.,u+s,go-rwwould set the setuid bit for a file's owner as well as remove read and write permission for the file's group and other users. an ls-style string of the formrwxrwxrwxis also accepted but must always be 9 characters long. e.g.,rwxr-xr-tis equivalent to01755.- on versions of Unix supporting file flags,
-readonlyreturns the value of, or sets, or clears the readonly attribute of a file, i.e., the user immutable flag (uchg) to thechflagscommand.
On Windows:
-archivegives the value or sets or clears the archive attribute of the file.-hiddengives the value or sets or clears the hidden attribute of the file.-longnamewill expand each path element to its long version. this attribute cannot be set.-readonlygives the value or sets or clears the readonly attribute of the file.-shortnamegives a string where every path element is replaced with its short (8.3) version of the name if possible. for path elements that cannot be mapped to short names, the long name is retained. this attribute cannot be set.-systemgives or sets or clears the value of the system attribute of the file.
On macOS and Darwin:
-creatorgives or sets the Finder creator type of the file.-hiddengives or sets or clears the hidden attribute of the file.-readonlygives or sets or clears the readonly attribute of the file.-rsrclengthgives the length of the resource fork of the file; this attribute can only be set to the value0, which results in the resource fork being stripped off the file.
On all platforms: files in zipfs mounted archives return the following attributes. these are all read-only and cannot be directly set, so don't even try it π€
-archiveβ the path of the mounted ZIP archive containing the file.-compsizeβ the compressed size of the file within the archive. this is0for directories.-crcβ the CRC of the file if present, else0.-mountβ the path where the containing archive is mounted.-offsetβ the offset of the file within the archive.-uncompsizeβ the uncompressed size of the file. this is0for directories.
other attributes may be present in the returned list. these should be ignored. like, mind your business, they're not for you π
file channels ?pattern?β ifpatternis not specified, returns a list of names of all registered open channels in this interpreter. ifpatternis specified, only those names matchingpatternare returned. matching is determined using the same rules as forstring match.file copy ?-force? ?--? source targetβ form one.file copy ?-force? ?--? source ?source ...? targetDirβ form two.
the first form makes a copy of the file or directory source under the pathname target. if target is an existing directory, then the second form is used instead. the second form makes a copy inside targetDir of each source file listed. if a directory is specified as a source, then the contents of the directory will be recursively copied into targetDir.
existing files will not be overwritten unless the -force option is specified (and when it is, Tcl will also attempt to adjust permissions on the destination file or directory if that's necessary to allow the copy to proceed β¨). when copying within a single filesystem, file copy will copy soft links β i.e. the links themselves are copied, not the things they point to.
heads up: trying to overwrite a non-empty directory, overwrite a directory with a file, or overwrite a file with a directory will all result in errors, even if -force was specified. no cap. π«
arguments are processed in the order specified, halting at the first error, if any. a -- marks the end of switches; the argument following the -- will be treated as a source even if it starts with a -.
file delete ?-force? ?--? ?pathname ...?β removes the file or directory specified by eachpathnameargument. non-empty directories will be removed only if the-forceoption is specified.
when operating on symbolic links, the links themselves will be deleted, not the objects they point to. trying to delete a non-existent file is not considered an error. trying to delete a read-only file will cause the file to be deleted, even if the -force flag is not specified. if the -force option is specified on a directory, Tcl will attempt both to change permissions and move the current directory pwd out of the given path if that's necessary to allow the deletion to proceed.
arguments are processed in the order specified, halting at the first error, if any. a -- marks the end of switches; the argument following the -- will be treated as a pathname even if it starts with a -.
file dirname nameβ returns a name comprised of all of the path components inname, excluding the last element. ifnameis a relative file name and only contains one path element, then it returns.. ifnamerefers to a root directory, then the root directory is returned. for example:
file dirname c:/
returns c:/. iconic, honestly.
file executable nameβ returns1if filenameis executable by the current user,0otherwise. on Windows, which does not have an executable attribute, the command treats all directories and any files with extensionsexe,com,cmdorbatas executable.file exists nameβ returns1if filenameexists and the current user has search privileges for the directories leading to it,0otherwise.file extension nameβ returns all of the characters innameafter and including the last dot in the last element ofname. if there is no dot in the last element ofname, then it returns the empty string.file home ?username?β if no argument is specified, the command returns the home directory of the current user. this is generally the value of the$HOMEenvironment variable, except that on Windows platforms backslashes in the path are replaced by forward slashes. an error is raised if the$HOMEenvironment variable is not set.
if username is specified, the command returns the home directory configured in the system for the specified user. note this may be different than the value of the $HOME environment variable, even when username corresponds to the current user. an error is raised if the username does not correspond to a user account on the system. π
file isdirectory nameβ returns1if filenameis a directory,0otherwise.file isfile nameβ returns1if filenameis a regular file,0otherwise.file join name ?name ...?β takes one or more file names and combines them, using the correct path separator for the current platform. if a particularnameis relative, then it will be joined to the previous file name argument. otherwise, any earlier arguments will be discarded, and joining will proceed from the current argument. for example:
file join a b /foo bar
returns /foo/bar. π«
note that any of the names can contain separators, and that the result is always canonical for the current platform: / for Unix and Windows.
file link ?-linktype? linkName ?target?β if only one argument is given, that argument is assumed to belinkName, and this command returns the value of the link given bylinkName(i.e. the name of the file it points to). iflinkNameis not a link or its value cannot be read (as, for example, seems to be the case with hard links, which look just like ordinary files), then an error is returned.
to be continued, bestie β there's more where this came from πΈ
okay so bestie, we were literally in the middle of file link, so let's just keep going, no notes π
If 2 arguments are given, those two are your linkName and your target. If linkName already exists, or if target doesn't exist, you get an error back. Otherwise? Tcl makes a brand new link called linkName that points at the existing filesystem object sitting at target β and that target is also the value you get returned, which is cute. The type of link is platform-specific, and on Unix a symbolic link is the default. This is the move when you want to create a link in a cross-platform way and you genuinely do not care which flavor of link you get. π«Ά
If you do care β like, you want a link of one specific type only, and you want an error if for some reason that's just not possible β then pass the optional -linktype argument. Accepted values for -linktype are -symbolic and -hard.
On Unix, symbolic links can be made to relative paths, and those paths have to be relative to the actual linkName's location (not to the cwd, bestie, this trips people up every time π). But on every other platform where relative links aren't supported, target paths always get converted to absolute, normalized form before the link is created β which means relative paths get interpreted as relative to the cwd. When you try to create links on filesystems that either don't support any links at all, or don't support the specific type you asked for, you get an error message. Most Unix platforms support both symbolic and hard links (the hard ones for files only). Windows supports symbolic directory links and hard file links on NTFS drives. no cap β¨
πΈ file lstat name ?varName?
Literally the same as the stat option (scroll down, it's right there) except it uses the lstat kernel call instead of stat. What that means in practice: if name points at a symbolic link, the info you get back is about the link itself, not the file it points to. On systems that don't support symbolic links, this option behaves exactly like the stat option. iconic behavior honestly π
π file mkdir ?dir ...?
Makes each directory you list. For each pathname dir you hand it, this command creates all the non-existing parent directories as well as dir itself β yes, it's giving mkdir -p energy, we love that. If you point it at a directory that already exists, nothing happens, no action taken, no error returned, chill vibes only. But trying to overwrite an existing file with a directory? That's an error, bestie. Arguments get processed in the order you specified, halting at the first error, if any. π¦
π file mtime name ?time?
Returns a decimal string of the time at which file name was last modified. If you pass time, that's a modification time to set for the file β equivalent to Unix touch. That time is measured the standard POSIX way, as seconds from a fixed starting time (often January 1, 1970). If the file doesn't exist, or its modified time can't be queried or set, an error gets generated. One lil caveat: on zipfs file systems, modification time cannot be explicitly set. π
π file nativename name
Returns the platform-specific name of the file. Super useful when you need the filename to pass to a platform-specific call β like handing it to a subprocess via exec under Windows (peep the EXAMPLES below). π
β file normalize name
Returns a unique normalized path representation for the filesystem object (file, directory, link, whatever), and that string value can be used as a unique identifier for it. A normalized path is an absolute path with all ../ and ./ removed. It's also one in the "standard" format for the native platform. On Unix, that means the segments leading up to the path have to be free of symbolic links/aliases β but the very last path component may be a symbolic link. On Windows it also means we want the long form with that form's case-dependence, which gives us a unique, case-dependent path.
That one exception about the last link in the path is necessary, actually, because Tcl or you the user might want to operate on the actual symbolic link itself β for example file delete, file rename, and file copy are defined to operate on symbolic links, not on the things they point to. main character energy for the symlink, honestly π
π
file owned name
Returns 1 if file name is owned by the current user, 0 otherwise. short. sweet. slay.
π§ file pathtype name
Returns one of absolute, relative, volumerelative. Breaking it down:
- If name refers to a specific file on a specific volume, the path type is
absolute. - If name refers to a file relative to the current working directory, the path type is
relative. - If name refers to a file relative to the current working directory on a specified volume, or to a specific file on the current working volume, the path type is
volumerelative.
π file readable name
Returns 1 if file name is readable by the current user, 0 otherwise. vibe check: passed or not, that's it β¨
π¦ file readlink name
Returns the value of the symbolic link given by name β i.e. the name of the file it points to. If name is not a symbolic link, or its value can't be read, an error is returned. Heads up: on systems that don't support symbolic links, this option is undefined. π
π₯ file rename ?-force? ?--? source target
π₯ file rename ?-force? ?--? source ?source ...? targetDir
The first form takes the file or directory specified by pathname source and renames it to target, moving the file if the pathname target specifies a name in a different directory. If target is an existing directory, then the second form is used instead.
The second form moves each source file or directory into the directory targetDir.
Existing files will not be overwritten unless the -force option is specified. When operating inside a single filesystem, Tcl will rename symbolic links rather than the things they point to. Trying to overwrite a non-empty directory, overwrite a directory with a file, or a file with a directory will all result in errors. Arguments are processed in the order specified, halting at the first error, if any. A -- marks the end of switches β the argument following the -- will be treated as a source even if it starts with a -. periodt. π
πΈ file rootname name
Returns all of the characters in name up to but not including the last . character in the last component of name. If the last component of name doesn't contain a dot, then it just returns name. simple as π
π file separator ?name?
If you give it no argument, it returns the character used to separate path segments for native files on this platform. If you give it a path, the filesystem responsible for that path gets asked to return its separator character. And if no file system accepts name? Error. generated. boom π
π file size name
Returns a decimal string giving the size of file name in bytes. If the file doesn't exist, or its size can't be queried, an error is generated.
β file split name
Returns a list whose elements are the path components in name. The first element of the list will have the same path type as name. All other elements will be relative. Path separators get discarded unless they're needed to make sure an element is unambiguously relative. iykyk π«Ά
π file stat name ?varName?
Invokes the stat kernel call on name, and returns a dictionary with the information returned from the kernel call. If varName is given, it uses that variable to hold the information. VarName is treated as an array variable, and in that case the command returns the empty string. The following elements get set: atime, ctime, dev, gid, ino, mode, mtime, nlink, size, type, uid.
Every element except type is a decimal string with the value of the corresponding field from the stat return structure β check the manual entry for stat for the details on what those values mean. The type element gives the type of the file in the same form returned by the command file type. π
π§ file system name
Returns a list of one or two elements. The first is the name of the filesystem to use for the file, and the second β if given β is an arbitrary string representing the filesystem-specific nature or type of the location within that filesystem. If a filesystem only supports one type of file, the second element may not be supplied.
For example, native files have a first element native, and a second element which, when given, is a platform-specific type name for the file's system (e.g. NTFS, FAT, on Windows). A generic virtual file system might return the list vfs ftp to represent a file on a remote ftp site mounted as a virtual filesystem through an extension called vfs. And if the file doesn't belong to any filesystem at all? An error is generated. π
π file tail name
Returns all of the characters in the last filesystem component of name. Any trailing directory separator in name is ignored. If name contains no separators, then it returns name. So, all of these:
file tail a/b
file tail a/b/
file tail b
return b. every single time. iconic. β¨
π
file tempdir ?template?
Creates a temporary directory β guaranteed to be newly created and writable by the current script β and returns its name. π
If template is given, it specifies one of, or both of:
- the existing directory (on a filesystem controlled by the operating system) to contain the temporary directory, and
- the base part of the directory name.
It's considered to have the location of the directory if there is a directory separator in the name, and the base part is everything after the last directory separator (if non-empty).
The default containing directory is determined by system-specific operations, and the default base name prefix is tcl.
The following output is typical and illustrative; the actual output will vary between platforms:
% file tempdir
/var/tmp/tcl_u0kuy5
% file tempdir /tmp/myapp
/tmp/myapp_8o7r9L
% file tempdir /tmp/
/tmp/tcl_1mOJHD
% file tempdir myapp
/var/tmp/myapp_0ihS0n
πΈ file tempfile β the temporary-file factory πΈ
file tempfile ?nameVar? ?template?
Spins up a temporary file for you and hands back a read-write channel opened on that file. So cute, so useful. π
- If you pass nameVar, that's a variable, and the name of the temp file gets written into it. If you don't pass it, Tcl will try to arrange for the temporary file to be deleted once it's no longer required β the self-cleaning queen π
- If template is present, it specifies parts of the filename template to use when creating it (stuff like the directory, base-name or extension). BUT β and this is important bestie β some platforms may ignore some or all of these parts and use a built-in default instead. So it's giving "suggestion, not a promise." π
Note that temporary files are only ever created on the native filesystem. As such, they can be relied upon to be used with operating-system native APIs and external programs that require a filename. β¨
π¦ file tildeexpand β the ~ whisperer π¦
file tildeexpand name
Returns the result of performing tilde substitution on name, no cap. Here's the tea β:
- If name begins with a tilde, then the file name will be interpreted as if the first element is replaced with the location of the home directory for the given user.
- If that tilde is followed immediately by a path separator, the
$HOMEenvironment variable is substituted. Easy. - Otherwise, the characters between the tilde and the next separator are taken as a user name, which is used to retrieve that user's home directory for substitution. (Yes, like
~fredenergy. Very main character of you to look up someone else's home. π ) - An error is raised if the
$HOMEenvironment variable or the user does not exist. π
And if the file name does not begin with a tilde? It's returned unmodified. Zero drama, zero changes. Slay. π
β¨ file type β vibe check the file β¨
file type name
Returns a string giving the type of file name. It'll be one of:
filedirectorycharacterSpecialblockSpecialfifolinksocket
That's the whole list, fr fr. Pick your fighter. π₯
π file volumes β the mount report π
file volumes
Returns the absolute paths to the volumes mounted on the system, as a proper Tcl list. Iconic behaviour, honestly.
Without any additional virtual filesystems mounted as root volumes, on UNIX, the command will return //zipfs:/ or / (in case of a --disable-zipfs build), since all filesystems are locally mounted. π§
On Windows, it will return a list of the available local drives (e.g. //zipfs:/ C:/). And if any virtual filesystem has mounted additional volumes, they will be in the returned list too. No volume left behind. π«Ά
π
file writable β yes or no, bestie π
file writable name
Returns 1 if file name is writable by the current user, 0 otherwise. Binary answer, no essay required. β
π PORTABILITY ISSUES π
Because different platforms do different things, and we respect their choices. π
π Unix
These commands always operate using the real user and group identifiers, not the effective ones. Real ones. Periodt. π
π₯ Windows
The file owned subcommand uses the user identifier (SID) of the process token, not the thread token which may be impersonating some other user. Sneaky thread tokens stay out of this convo. π
β EXAMPLES β
This procedure shows how to search for C files in a given directory that have a correspondingly-named object file in the current directory:
proc findMatchingCFiles {dir} {
set files {}
switch $::tcl_platform(platform) {
windows {
set ext .obj
}
unix {
set ext .o
}
}
foreach file [glob -nocomplain -directory $dir *.c] {
set objectFile [file tail [file rootname $file]]$ext
if {[file exists $objectFile]} {
lappend files $file
}
}
return $files
}
Rename a file and leave a symbolic link pointing from the old location to the new place:
set oldName foobar.txt
set newName foo/bar.txt
# Make sure that where we're going to move to exists...
if {![file isdirectory [file dirname $newName]]} {
file mkdir [file dirname $newName]
}
file rename $oldName $newName
file link -symbolic $oldName $newName
On Windows, a file can be βstartedβ easily enough (equivalent to double-clicking on it in the Explorer interface) but the name passed to the operating system must be in native format:
exec {*}[auto_execok start] {} [file nativename C:/Users/fred/example.txt]
π«Ά SEE ALSO π«Ά
The whole squad, go say hi:
filename(3tcl)open(3tcl)close(3tcl)eof(3tcl)gets(3tcl)tell(3tcl)seek(3tcl)fblocked(3tcl)flush(3tcl)
πΈ KEYWORDS πΈ
attributescopy filesdelete filesdirectoryfilemove filesnamerename filesstatuser
Okay bestie, that's the whole page, start to finish. This lil masterpiece ships as part of Tcl 8.3, and it's the file(3tcl) manual. Go forth and manipulate files responsibly, ily, mwah πβ¨ππ¦
π¦ where this page comes from
- ubuntu stonking: tcl9.0-doc 9.0.4+dfsg-1
- Copyright (c) 1993 The Regents of the University of California
- Copyright (c) 1994-1996 Sun Microsystems, Inc
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms