file - Manipulate file names and attributes http://purl.org/tcl/home/man/tcl8.5/TclCmd/file.htm '''file''' ''option name ?arg arg ...?'' This command provides several operations on a file's name or attributes. ''Name'' is the name of a file; if it starts with a tilde, then tilde substitution is done before executing the command (see the manual entry for '''[filename]''' for details). ''Option'' indicates what to do with the file ''name''. Any unique abbreviation for ''option'' is acceptable. The valid options are: (see complete man page; here's only notes on selected options). ---- '''[file atime]''' ''name ?time?'' '''[file attributes]''' ''name'' '''[file attributes]''' ''name ?option?'' '''[file attributes]''' ''name ?option value option value...?'' '''[file channels]''' ''?pattern?'' '''[file copy]''' ''?'''''-force'''''? ?'''''--'''''? source target'' '''[file copy]''' ''?'''''-force'''''? ?'''''--'''''? source ?source ...? targetDir'' '''[file delete]''' ''?'''''-force'''''? ?'''''--'''''? pathname ?pathname ... ?'' '''[file dirname]''' ''name'' '''[file executable]''' ''name'' '''[file exists]''' ''name'' '''[file extension]''' ''name'' '''[file isdirectory]''' ''name'' '''[file isfile]''' ''name'' '''[file join]''' ''name ?name ...?'' '''[file link]''' ''?-linktype? linkName ?target?'' (requires Tcl8.4) '''[file lstat]''' ''name varName'' '''[file mkdir]''' ''dir ?dir ...?'' '''[file mtime]''' ''name ?time?'' '''[file nativename]''' ''name'' '''[file normalize]''' ''name'' (requires Tcl8.4) '''[file owned]''' ''name'' '''[file pathtype]''' ''name'' '''[file readable]''' ''name'' '''[file readlink]''' ''name'' '''[file rename]''' ''?'''''-force'''''? ?'''''--'''''? source target'' '''[file rename]''' ''?'''''-force'''''? ?'''''--'''''? source ?source ...? targetDir'' '''[file rootname]''' ''name'' '''[file separator]''' ''?name?'' '''[file size]''' ''name'' '''[file split]''' ''name'' '''[file stat]''' ''name varName'' '''[file system]''' ''name'' (requires Tcl8.4) '''[file tail]''' ''name'' '''[file type]''' ''name'' '''[file volumes]''' '''[file writable]''' ''name'' ---- [[Hopefully someone will provide some samples to show how these are useful. With the new [VFS] support in [Tcl] 8.4, and an appropriate extension, '''file''' can operate on much more than just local files (see the [One-line web browser in Tcl] for example).]] ---- '''Can someone comment on what happens if the current working directory is on a different drive?''' Yes. The question is essentially nonsensical because the current working directory is a per-drive attribute. What happens if I try to open the door, but the other door is open? Hmm , so the following sequence, in Windows, is nonsense? cd C:/tcl/lib set fd [open "G:list.txt" "w"] set lst [glob *] puts $fd $lst close $fd Interesting- I never realized that Windows was so brain-damaged. ---- [LES]: One may want to use this [proc] to catch a quick grasp of and/or memorize all the [file] commands: proc fileinfo { myFile } { puts "file name: $myFile" puts "exists: [ file exists $myFile ]" puts "----------------" puts "type: [ file type $myFile ]" puts "size: [ file size $myFile ]" puts "" puts "atime: [ file atime $myFile ]" puts "mtime: [ file mtime $myFile ]" puts "" puts "pathtype: [ file pathtype $myFile ]" puts "dirname: [ file dirname $myFile ]" puts "separator: [ file separator $myFile ]" puts "nativename: [ file nativename $myFile ]" puts "normalize: [ file normalize $myFile ]" puts "rootname: [ file rootname $myFile ]" puts "tail: [ file tail $myFile ]" puts "extension: [ file extension $myFile ]" puts "join: [ file join $myFile ]" puts "" puts "attributes: [ file attributes $myFile ]" puts "owned: [ file owned $myFile ]" puts "readable: [ file readable $myFile ]" puts "writable: [ file writable $myFile ]" puts "executable: [ file executable $myFile ]" puts "" puts "channels: [ file channels $myFile ]" puts "system: [ file system $myFile ]" } run it: '''$ fileinfo somefile.txt''' [IL] problems identifying what you're looking at? the following proc returns a simple string detailing what you have available to you. This is not great coding, but makes up for some TCL 8.3 ambiguities that might lead a programmer astray due to some assumptions. It also should rid you of the trailing slash problem. proc setloctype { loc { ambigtofile "false" } } { # define a location as a directory or file or both. # also identifies location as absolute or relative # # * manually choose to prefer files over directories when resolving ambiguous references if needed # # examples: # /mydirectory/name - absolute_dir # logs/reports.log - relative_file_dir # /restartfarms.sh - absolute_file set tailtype "" if { [string range $loc end end] == "/" } { set tail "" set loc [string range $loc 0 end-1] set tailtype "dir" } else { set tail [file tail $loc] if { [regexp "\\." $loc] || [string is true $ambigtofile] } { set tailtype "file" } else { set tailtype "dir" } } switch [file pathtype $loc] { "absolute" { switch [regexp -all "/" $loc] { "1" { if { $tailtype == "file" } { set loctype "absolute_file" } else { set loctype "absolute_dir" } } default { if { $tailtype == "file" } { set loctype "absolute_file_dir" } else { set loctype "absolute_dir" } } } } "relative" - default { switch [regexp -all "/" $loc] { "0" { if { $tailtype == "file" } { set loctype "relative_file" } else { set loctype "relative_dir" } } default { if { $tailtype == "file" } { set loctype "relative_file_dir" } else { set loctype "relative_dir" } } } } } return $loctype } ---- [JH] I wanted to get a relative path based on another path and couldn't find a proc that did it, so here is one I made (with minimal testing): proc relpath {basedir target} { # Try and make a relative path to a target file/dir from base directory set bparts [file split [file normalize $basedir]] set tparts [file split [file normalize $target]] if {[lindex $bparts 0] eq [lindex $tparts 0]} { # If the first part doesn't match - there is no good relative path set blen [llength $bparts] set tlen [llength $tparts] for {set i 1} {$i < $blen && $i < $tlen} {incr i} { if {[lindex $bparts $i] ne [lindex $tparts $i]} { break } } set path [lrange $tparts $i end] for {} {$i < $blen} {incr i} { set path [linsert $path 0 ..] } return [eval [list file join] $path] } return $target } # Some examples relpath C:/Tcl/lib/tcllib C:/Tcl/lib/tcllib/module/pkgIndex.tcl # module/pkgIndex.tcl relpath [file dirname [info nameofexe]] [info library] # ../lib/tcl8.4 relpath C:/Tcl/foo D:/Tcl/bar # D:/Tcl/bar relpath /usr/bin /usr/local/bin/tclsh # ../local/bin/tclsh [MG] Edited so that it runs ''file normalize'' on both paths first - still works the same with all the examples above, but also handles, for instance cd "c:/program files/tcl/" relpath . [info library] # lib/tcl8.4 when one path is relative and one isn't. I was going to suggest return [join $path [file separator]] instead of return [eval [list file join] $path] to remove the eval, but for me (on Windows XP) that returns a different result - [file separator] returns a '''\''', while [file join] joins using a '''/'''. Using return [file normalize [join $path [file separator]]] would remove the need for [eval] and still return the same result as [file join], I think. Is it intended that they (file separator and file join) use different characters on Windows? The docs for both say they use the "native character for the platform"... [JH] The [file join] and [file separator] differences are intentional. Note that you can use [file nativename] to also get native again. ---- [Csan] How about a [file mkfifo] instead of [exec mkfifo]? Would be a lifesaver for us, un*x users... ---- [MHo]: I'm confused: % glob -types hidden -dir //wa101su052.prod01.hmkintra.de/c\$ * {//wa101su052.prod01.hmkintra.de/c$/boot.ini} {//wa101su052.prod01.hmkintra.de/c$/bootfont.bin} {//w a101su052.prod01.hmkintra.de/c$/Config.Msi} {//wa101su052.prod01.hmkintra.de/c$/IO.SYS} {//wa101su05 2.prod01.hmkintra.de/c$/MSDOS.SYS} {//wa101su052.prod01.hmkintra.de/c$/NTDETECT.COM} {//wa101su052.p rod01.hmkintra.de/c$/ntldr} {//wa101su052.prod01.hmkintra.de/c$/pagefile.sys} {//wa101su052.prod01.h mkintra.de/c$/System Volume Information} % glob -types hidden -dir //wa101su052.prod01.hmkintra.de/c\$ pagefile.sys no files matched glob pattern "pagefile.sys" % file size //wa101su052.prod01.hmkintra.de/c\$/pagefile.sys could not read "//wa101su052.prod01.hmkintra.de/c$/pagefile.sys": no such file or directory % Does this mean we can't operate on hidden and/or system files (MS Win)? While glob lists 'pagefile.sys', the file command ignores it... ---- See also: * [filesystem benchmarking] * [How do I remove one line from a file?] ---- !!!!!! [Arts and Crafts of Tcl-Tk Programming] - [Additional file commands] %| [Tcl syntax help] | [Category Command] | [Category File] |% !!!!!!