:TITLE: Information about Files - file, glob ;# ;# RCSID: $Header: /cvsroot/tcl/tcltutorial/original/Tcl25.lsn,v 1.1 2004/11/04 16:01:14 davidw Exp $ ;# Copyright (c) 1995 Clif Flynt ;# 9300 Fleming Rd. ;# Dexter, MI 48130 ;# clif@cflynt.com ;# See file "NOTICE" for licensing terms. ;# ::CMD:: if {([info exists tcl_platform])} { switch $tcl_platform(platform) { unix { set Tutor(lsn.codeMod) { {regsub "PATTERN1" $line "/usr/bin/*ail*" line} {regsub "PATTERN2" $line "/bin/*ail*" line} } } windows { set Tutor(lsn.codeMod) { {if {[glob -nocomplain C:/winnt] != ""} { regsub "PATTERN1" $line "C:/winnt/system32/w*.dll" line regsub "PATTERN2" $line "C:/winnt/system32/win*.exe" line } else { regsub "PATTERN1" $line "C:/windows/w*.dll" line regsub "PATTERN2" $line "C:/windows/win*.exe" line } } } } mac { set Tutor(lsn.codeMod) { } } default { puts "I don't recognize the platform: $tcl_platform(platform)" puts "Can't set platform specific parameters" } } } :LESSON_TEXT_START_LEVEL 0: There are two commands that provide information about the contents of directories and the files within those directories. These two commands are glob and file.

Glob provides the access to the names of files in a directory. It is similar to the ls shell command.

File provides services similar to those provided by the stat(2) call

glob ?switches? pattern ?pattern?
returns a list of file names that match pattern

Switches may be one of:

-nocomplain
Allows glob to return an empty list without causing an error. Without this flag, an error would be generated when the empty list was returned.
--
Marks the end of switches. This allows the use of "-" in a pattern without confusing the glob parser.
Pattern follows the same matching rules as the string match globbing rules with these exceptions: Note that the filenames that match pattern are not in a sorted order.
file atime name
Returns the number of seconds since 1/1/1970 when the file name was last accessed. Generates an error if the file doesn't exist, or the access time cannot be queried.
file dirname name
Returns the directory portion of a path/filename string. If name contains no slashes, file dirname returns a ".". If the last "/" in name is also the first character, it returns a "/".
file executable name
Returns a 1 if file name is executable by the current user, otherwise returns a 0.
file exists name Returns a 1 if the file name exists, and the user has search access in all the directories leading to the file. Otherwise, a 0 is returned.
file extension name
Returns the file extension.
file isdirectory name
Returns 1 if file name is a directory, otherwise returns 0.
file isfile name
Returns 1 if file name is a regular file, otherwise returns 0.
file lstat name varName This returns the same information returned by the system call lstat. The results are placed in the associative array varName. The indexes in varName are: Because this calls lstat, if name is a symbolic link, the values in varName will refer to the link, not the file that is linked to.

See stat also.

file mtime name
Returns the time of the last data modification in seconds since Jan 1, 1970.
file owned name
Returns 1 if the file is owned by the current user, otherwise returns 0.
file readable name
Returns 1 if the file is readable by the current user, otherwise returns 0.
file readlink name
Returns the name of the file a symlink is pointing to. If name isn't a symlink, or can't be read, an error is generated.
file rootname name
Returns all the characters in name up to but not including the last ".". Returns $name if name doesn't include a ".".
file size name
Returns the size of name in bytes.
file stat name varName This returns the same information returned by the system call stat. The results are placed in the associative array varName. The indexes in varName are:
file tail name
Returns all of the characters in name after the last slash. Returns $name if name contains no slashes.
file type name
Returns a string giving the type of file name, which will be one of:
file writable name
Returns 1 if file name is writable by the current user, otherwise returns 0.
:TEXT_END: :LESSON_TEXT_START_LEVEL 1: There are two commands that provide information about the file system, glob and file.

Glob provides the access to the names of files in a directory. It uses a name matching mechanism similar to ls, to return a list of names that match a pattern.

File provides two sets of functionality:

Between these two commands, a program can obtain most of the information that it may need.
glob ?switches? pattern ?patternN?
returns a list of file names that match pattern or patternN

Switches may be one of:

-nocomplain
Allows glob to return an empty list without causing an error. Without this flag, an error would be generated when the empty list was returned.
--
Marks the end of switches. This allows the use of "-" in a pattern without confusing the glob parser.
Pattern follows the same matching rules as the string match globbing rules with these exceptions: Note that the filenames that match pattern are not in a sorted order.
file atime name
Returns the number of seconds since 1/1/1970 when the file name was last accessed. Generates an error if the file doesn't exist, or the access time cannot be queried.
file dirname name
Returns the directory portion of a path/filename string. If name contains no slashes, file dirname returns a ".". If the last "/" in name is also the first character, it returns a "/".
file executable name
Returns a 1 if file name is executable by the current user, otherwise returns a 0.
file exists name Returns a 1 if the file name exists, and the user has search access in all the directories leading to the file. Otherwise, a 0 is returned.
file extension name
Returns the file extension.
file isdirectory name
Returns 1 if file name is a directory, otherwise returns 0.
file isfile name
Returns 1 if file name is a regular file, otherwise returns 0.
file lstat name varName This returns the same information returned by the system call lstat. The results are placed in the associative array varName. The indexes in varName are: Because this calls lstat, if name is a symbolic link, the values in varName will refer to the link, not the file that is linked to.

See stat also.

file mtime name
Returns the time of the last data modification in seconds since Jan 1, 1970.
file owned name
Returns 1 if the file is owned by the current user, otherwise returns 0.
file readable name
Returns 1 if the file is readable by the current user, otherwise returns 0.
file readlink name
Returns the name of the file a symlink is pointing to. If name isn't a symlink, or can't be read, an error is generated.
file rootname name
Returns all the characters in name up to but not including the last ".". Returns $name if name doesn't include a ".".
file size name
Returns the size of name in bytes.
file stat name varName This returns the same information returned by the system call stat. The results are placed in the associative array varName. The indexes in varName are:
file tail name
Returns all of the characters in name after the last slash. Returns $name if name contains no slashes.
file type name
Returns a string giving the type of file name, which will be one of:
file writable name
Returns 1 if file name is writable by the current user, otherwise returns 0.
:TEXT_END: :LESSON_TEXT_START_LEVEL 2: There are two commands that provide information about the file system, glob and file.

Glob provides the access to the names of files in a directory. It uses a name matching mechanism similar to ls, to return a list of names that match a pattern.

File provides two sets of functionality:

Between these two commands, a program can obtain most of the information that it may need.
glob ?switches? pattern ?patternN?
returns a list of file names that match pattern or patternN

Switches may be one of:

-nocomplain
Allows glob to return an empty list without causing an error. Without this flag, an error would be generated when the empty list was returned.
--
Marks the end of switches. This allows the use of "-" in a pattern without confusing the glob parser.
Pattern follows the same matching rules as the string match globbing rules with these exceptions: Note that the filenames that match pattern are not in a sorted order.
file atime name
Returns the number of seconds since 1/1/1970 when the file name was last accessed. Generates an error if the file doesn't exist, or the access time cannot be queried.
file dirname name
Returns the directory portion of a path/filename string. If name contains no slashes, file dirname returns a ".". If the last "/" in name is also the first character, it returns a "/".
file executable name
Returns a 1 if file name is executable by the current user, otherwise returns a 0.
file exists name Returns a 1 if the file name exists, and the user has search access in all the directories leading to the file. Otherwise, a 0 is returned.
file extension name
Returns the file extension.
file isdirectory name
Returns 1 if file name is a directory, otherwise returns 0.
file isfile name
Returns 1 if file name is a regular file, otherwise returns 0.
file lstat name varName This returns the same information returned by the system call lstat. The results are placed in the associative array varName. The indexes in varName are: Because this calls lstat, if name is a symbolic link, the values in varName will refer to the link, not the file that is linked to.

See stat also.

file mtime name
Returns the time of the last data modification in seconds since Jan 1, 1970.
file owned name
Returns 1 if the file is owned by the current user, otherwise returns 0.
file readable name
Returns 1 if the file is readable by the current user, otherwise returns 0.
file readlink name
Returns the name of the file a symlink is pointing to. If name isn't a symlink, or can't be read, an error is generated.
file rootname name
Returns all the characters in name up to but not including the last ".". Returns $name if name doesn't include a ".".
file size name
Returns the size of name in bytes.
file stat name varName This returns the same information returned by the system call stat. The results are placed in the associative array varName. The indexes in varName are:
file tail name
Returns all of the characters in name after the last slash. Returns $name if name contains no slashes.
file type name
Returns a string giving the type of file name, which will be one of:
file writable name
Returns 1 if file name is writable by the current user, otherwise returns 0.

The example shows a way of using these commands to build a table of file names, directories, inodes, and types.

The first two lines of code use the glob to make two lists (ail1, ail2) of files in /bin and /usr/bin which contain the string ail as part of their name. This will include all of the various mail related programs, some of which may be symbolic links to other files.

The next two lines of code use the format command to print out column headers for the data that will be displayed by the rest of the code. The %- construct forces these fields to be left justified, which looks better in a table. This is not done for the third field because that field will be the inode number, and numbers look better right justified.

Next, the program loops through all of the names that were acquired with the glob command. Concat is used to combine the two lists into a single list. If list were used, like this:

foreach name [list $ail1 $ail2]
it would treat $ail1 and $ail2 as single entities, and make a list resembling:
{ail1/file1 ail1/file2} {ail2/file1 ail2/file2}
which would cause all of the file commands to fail, since "ail1/file1 ail1/file2" is not the name of a file.

The file name is split into the directory and entry portions of the name using the file dirname and file tail commands.

The file stat command is used to build an associative array of the various status fields for the entry. The only one we'll use is the ino, which is the inode of the file. There is a good chance that there will be two files displayed that have the same inode, but are listed as regular files. These are 'normal' links, rather than symbolic links.

The results of these commands is displayed with a puts command using the '-nonewline' option. This option causes puts to append a newline. In this case, it lets us add a comment to each line of data after it has been printed.

Finally, if the type of $name is a file, the size is printed, and if the type is a symbolic link, then the file it is linked to is printed.

For practice, try changing the directory to /dev, glob on the disk drives and tty's, and see what the types are displayed as. :TEXT_END: :CODE_START: ;# Collect a bunch of files to compare set ail1 [glob PATTERN1] set ail2 [glob PATTERN2] ;# Set the format string (see Lsn.18), and display column headers set fmt "%-12s %-16s %8s %-7s" puts "[format "$fmt Comment" "Directory" "Name" "Inode" "Type"]" ;# Loop through the filenames collected by glob, and ;# determine their inode, size, and type. ;# Then display the results. foreach name [concat $ail1 $ail2] { ;# split the name into pieces for display: set dir [file dirname $name] set filename [file tail $name] ;# Collect some status and type info. file stat $name arr set type [file type $name] ;# Display what we've learned. puts -nonewline "[format $fmt $dir $filename $arr(ino) $type]" ;# and particular data depending on whether item is a file or symbolic link. if {[string match [file type $name] "link"]} { puts " points to: [file readlink $name]" } if {[string match [file type $name] "file"]} { puts " Size: [file size $name] bytes " } } :TEXT_END: