Those migrating from shell (or batch) programming to Perl often expect that a Perl script is like a shell script—just a sequence of UNIX/Linux (or MS-DOS) commands. However, system utilities are not accessed directly in Perl programs as they are in shell scripts. Of course, to be effective there must be some way in which your Perl program can interface with the operating system. Perl has a set of functions, in fact, that specifically interface with the operating system and are directly related to the UNIX/Linux system calls so often found in C programs. Many of these system calls are supported by Windows. The ones that are generally not supported are found at the end of this chapter.
A system call requests some service from the operating system (kernel), such as getting the time of day, creating a new directory, removing a file, creating a new process, terminating a process, and so on. A major group of system calls deals with the creation and termination of processes, how memory is allocated and released, and sending information (e.g., signals) to processes. Another function of system calls is related to the file system: file creation, reading and writing files, creating and removing directories, creating links, etc.[1]
[1] System calls are direct entries into the kernel, whereas library calls are functions that invoke system calls. Perl's system interface functions are named after their counterpart UNIX system calls in Section 2 of the UNIX manual pages.
The UNIX[2] system calls are documented in Section 2 of the UNIX manual pages. Perl's system functions are almost identical in syntax and implementation. If a system call fails, it returns a –1 and sets the system's global variable errno to a value that contains the reason the error occurred. C programs use the perror function to obtain system errors stored in errno; Perl programs use the special $! variable. (See "Error Handling" on page 755.)
[2] From now on when referring to UNIX, assume that Linux also applies.
The following Perl functions allow you to perform a variety of calls to the system when you need to manipulate or obtain information about files or processes. If the system call you need is not provided by Perl, you can use Perl's syscall function, which takes a UNIX system call as an argument. (See"The syscall Function and the h2ph Script" on page 747.)
In addition to the built-in functions, the standard Perl library comes bundled with a variety of over 200 modules that can be used to perform portable operations on files, directories, processes, networks, etc. If you installed ActiveState, you will also find a collection of Win32 modules in the standard Perl library under C:\perl\site\lib\Win32.
To read the documentation for any of the modules (filenames with a .pm extension) from the standard Perl library, use the Perl built-in perldoc function or the UNIX man command. ActiveState (Win32) provides online documentation found by clicking the Start button, Programs, and then ActiveState.
When walking through a file system, directories are separated by slashes. UNIX file systems indicate the root directory with a forward slash (/), followed by subdirectories separated by forward slashes where, if a filename is specified, it is the final component of the path. The names of the files and directories are case sensitive, and their names consist of alphanumeric characters and punctuation, excluding whitespace. A period in a filename has no special meaning but can be used to separate the base filename from its extension, such as in program.c or file.bak. The length of the filename varies from different operating systems, with a minimum of 1 character, and on most UNIX-type file systems, up to 255 characters are allowed. Only the root directory can be named / (slash).[3]
[3] The Mac OS file system (HFS) is also hierarchical and uses colons to separate path components.
Win32 file systems, mainly FAT, FAT32, and NTFS, use a different convention for specifying a directory path. Basic FAT directories and files are separated by a backslash (\). Their names are case insensitive and start with a limit of 8 characters, followed by a period, and a suffix of no more than 3 characters. (Windows 2000/NT allow longer filenames.) The root of the file system is a drive number, such as C:\ or D:\, rather than only a slash. In networked environments, the universal naming convention (UNC) uses a different convention for separating the components of a path; the drive letter is replaced with two backslashes, as in \\myserver\dir\dir.
The backslash in Perl scripts is used as an escape or quoting character (\n, \t,\U, \$500, etc.), so when specifying a Win32 path separator, two backslashes are often needed, unless a particular module allows a single backslash or the pathname is surrounded by single quote. For example, C:\Perl\lib\File should be written C:\\Perl\\lib\\File.
The File::Spec module found in the standard Perl library was designed to portably support operations commonly performed on filenames, such as creating a single path out of a list of path components and applying the correct path delimiter for the appropriate operating system or splitting up the path into volume, directory, and filename, etc. A list of File::Spec functions is provided in Table 18.1.
Since these functions are different for most operating systems, each set of OS-specific routines is available in a separate module, including:
File::Spec::UNIX
File::Spec::Mac
File::Spec::OS2
File::Spec::Win32
File::Spec::VMS
1 use File::Spec; 2 $pathname=File::Spec->catfile("C:","Perl","lib","CGI"); 3 print "$pathname\n"; (Output) 3 C:\Perl\lib\CGI Explanation |
The most common type of file is a regular file. It contains data, an ordered sequence of bytes. The data can be text data or binary data. Information about the file is stored in a system data structure called an inode. The information in the inode consists of such attributes as the link count, the owner, the group, mode, size, last access time, last modification time, and type. The UNIX ls command lets you see the inode information for the files in your directory. This information is retrieved by the stat system call. Perl's stat function also gives you information about the file. It retrieves the device number, inode number, mode, link count, user ID, group ID, size in bytes, time of last access, and so on. (See "The stat and lstat Functions" on page 710.)
A directory is a specific file maintained by the UNIX kernel. It is composed of a list of filenames. Each filename has a corresponding number that points to the information about the file. The number, called an inode number, is a pointer to an inode. The inode contains information about the file as well as a pointer to the location of the file's data blocks on disk. The following functions allow you to manipulate directories, change permissions on files, create links, etc.
Directory Entry | |
Inode # | Filename |
Files and directories contain data as well as metainformation that describes attributes of a file or directory. The four basic attributes of Win32 files and directories are ARCHIVE, HIDDEN, READONLY, and SYSTEM. See Table 18.2.
To retrieve and set file attributes, use the standard Perl extension Win32::File. All of the functions return FALSE (0) if they fail, unless otherwise noted. The function names are exported into the caller's namespace by request. See Table 18.3.
Function | What It Does |
---|---|
GetAttributes(Filename, ReturnedAttributes) | Gets attributes of a file or directory. ReturnedAttributes will be set to the ored combination of the filename attributes. |
SetAttributes(Filename, NewAttributes) | Sets the attributes of a file or directory. newAttributes must be an ored combination of the attributes. |
To retrieve file attributes, use Win32::File::GetAttributes($Path, $Attributes), and to set file attributes, use Win32::File::SetAttributes($Path,$Attributes). See Table 18.4. The Win32::File also provides a number of constants; see Example 18.3.
Attribute | Description |
---|---|
ARCHIVE | Set when file content changes. Used by backup programs. |
COMPRESSED | Windows compressed file, not a zip file. Cannot be set by the user. |
DIRECTORY | File is a directory. Cannot be set by the user. |
HIDDEN | A file not shown in a directory listing. |
NORMAL | A normal file. ARCHIVE, HIDDEN, READONLY, and SYSTEM are not set. |
OFFLINE | Data is not available. |
READONLY | A file that cannot be changed. |
SYSTEM | Special system files, such as IO.SYS and MS-DOS.SYS, normally invisible. |
TEMPORARY | File created by some program. |
The File::Find module lets you traverse a file system tree for specified files or directories based on some criteria, like the UNIX find command or the Perl find2perl translator.
Formatuse File::Find; find(\&wanted, '/dir1', '/dir2'); sub wanted { ... } |
The first argument to find() is either a hash reference describing the operations to be performed for each file or a reference to a subroutine. Type perldoc File::Find for details. The wanted() function does whatever verification you want for the file. $File::Find::dir contains the current directory name, and $_ is assigned the current filename within that directory. $File::Find::name contains the complete pathname to the file. You are chdir()ed to $File::Find::dir when the function is called, unless no_chdir was specified. The first argument to find() is either a hash reference describing the operations to be performed for each file or a code reference.
The mkdir function creates a new, empty directory with the specified permissions (mode). The permissions are set as an octal number. The entries for the . and .. directories are automatically created. The mkdir function returns 1 if successful and 0 if not. If mkdir fails, the system error is stored in Perl's $! variable.
If creating a directory at the MS-DOS prompt, the permission mask has no effect. Permissions on Win32 don't use the same mechanism as UNIX. For files on FAT partitions (which means all files on Windows 95), you don't have to set permissions explicitly on a file. All files are available to all users, and the directory is created with all permissions turned on for everyone.
# This script is called "makeit" 1 die "$0 <directory name> " unless $#ARGV == 0; 2 mkdir ($ARGV[0], 0755 ) || die "mkdir: $ARGV[0]: $!\n"; (At The Command Line) $ makeit 1 makeit <directory name> at makeit line 3. $ makeit joker 2 makeit: joker: File exists $ makeit cabinet $ ls -d cabinet cabinet Explanation |
The rmdir function removes a directory but only if it is empty.
Formatrmdir(DIRECTORY); rmdir DIRECTORY; Example 18.8.
|
Each process has its own present working directory. When resolving relative path references, this is the starting place for the search path. If the calling process (e.g., your Perl script) changes the directory, it is changed only for that process, not the process that invoked it, normally the shell. When the Perl program exits, the shell returns with the same working directory it started with.
The chdir function changes the current working directory. Without an argument, the directory is changed to the user's home directory. The function returns 1 if successful and 0 if not. The system error code is stored in Perl's $! variable.[4]
[4] chdir is a system call provided with Perl for changing directories. The cd command used at the command line is a shell built-in and cannot be used directly in a Perl script.
Formatchdir (EXPR); chdir EXPR; chdir; Example 18.9.
|
The following Perl directory functions are modeled after the UNIX system calls sharing the same name. Although the traditional UNIX directory contained a 2-byte inode number and a 14-byte filename (Figure 18.2), not all UNIX systems have the same format. The directory functions allow you to access the directory regardless of its internal structure. The directory functions work the same way with Windows.
The opendir function opens a named directory and attaches it to the directory filehandle. This filehandle has its own namespace, separate from the other types of filehandles used for opening files and filters. The opendir function initializes the directory for processing by the related functions readdir(), telldir(), seekdir(), rewinddir(), and closedir(). The function returns 1 if successful.
Formatopendir(DIRHANDLE, EXPR) Example 18.10.
|
A directory can be read by anyone who has read permission on the directory. You can't write to the directory itself even if you have write permission. The write permission on a directory means that you can create and remove files from within the directory, not alter the directory data structure itself.
When we speak about reading a directory with the readdir function, we are talking about looking at the contents of the directory structure maintained by the system. If the opendir function opened the directory, in a scalar context, readdir returns the next directory entry. The readdir function returns the next directory entry. In an array context, it returns the rest of the entries in the directory.
Formatreaddir(DIRHANDLE); readdir DIRHANDLE; |
The closedir function closes the directory that was opened by the opendir function.
Formatclosedir (DIRHANDLE); closedir DIRHANDLE; Example 18.11.
|
The telldir function returns the current position of the readdir() routines on the directory filehandle. The value returned by telldir may be given to seekdir() to access a particular location in a directory.
Formattelldir(DIRHANDLE); |
The rewinddir function sets the position of DIRHANDLE back to the beginning of the directory opened by opendir. It is not supported on all machines.
Formatrewinddir(DIRHANDLE); rewinddir DIRHANDLE; |
The seekdir sets the current position for readdir() on the directory filehandle. The position is set by the a value returned by telldir().
Formatseekdir(DIRHANDLE, POS); Example 18.12.
|
There is one owner for every UNIX file. The one benefit the owner has over everyone else is the ability to change the permissions on the file, thus controlling who can do what to the file. A group may have a number of members, and the owner of the file may change the group permissions on a file so that the group will enjoy special privileges.
Every UNIX file has a set of permissions associated with it to control who can read, write, or execute the file. There are a total of 9 bits that constitute the permissions on a file. The first 3 bits control the permissions of the owner of the file, the second set controls the permissions of the group, and the last set controls the rest of the world; that is, everyone else. The permissions are stored in the mode field of the file's inode.
Win32 systems do not handle file permissions the way UNIX does. Files are created with read and write turned on for everyone. Files and folders inherit attributes that you can set. By clicking the mouse on a file icon and selecting Properties, you can, in a limited way, select permission attributes, such as Archive, Read-only, and Hidden. See Figure 18.3.
If your platform is Windows NT, you can set file and folder permissions only on drives formatted to use NTFS.[5] To change permissions, you must be the owner or have been granted permission to do so by the owner. If you are using NTFS, go to Windows Explorer and then locate the file or folder for which you want to set permissions. Right-click the file or folder, click Properties, and then click the Security tab. You will be able to allow, deny, or remove permissions from the group or user.
[5] NTFS is an advanced file system designed for Windows NT.
See the Win32::FileSecurity module in the Perl Resource Kit for Win32 if you need to maintain file permissions. To retrieve file permissions from a file or directory, use the Win32::FileSecurity::Get($Path, \%Perms) extension, where $Path is the relative or absolute path to the file or directory for which you are seeking permissions, and \%Perms is a reference to a hash containing keys representing the user or group and corresponding values representing the permission mask.
Extension | What It Does |
---|---|
Win32::File | Standard module for retrieving and setting file attributes |
Win32::File::GetAtributes(path,attribute) | Retrieves file attributes |
Win32::File::SetAttributes(path,attribute) | Sets file attributes |
Win32::AdminMisc::GetFileInfo | Retrieves file information fields: CompanyName, FileVersion, InternalName, LegalCopyright, OriginalFileName, ProductName, ProductVersion, LangID, and Language |
The chmod function changes permissions on a list of files. The user must own the files to change permissions on them. The files must be quoted strings. The first element of the list is the numeric octal value for the new mode. (Today, the binary/octal notation has been replaced by a more convenient mnemonic method for changing permissions. Perl does not use the new method.)
Table 18.7 illustrates the eight possible combinations of numbers used for changing permissions if you are not familiar with this method.
Octal | Binary | Permissions | Meaning |
---|---|---|---|
0 | 000 | none | All turned off |
1 | 001 | --x | Execute |
2 | 010 | -w- | Write |
3 | 011 | -wx | Write, execute |
4 | 100 | r-- | Read |
5 | 101 | r-x | Read, execute |
6 | 110 | rw- | Read, write |
7 | 111 | rwx | Read, write, execute |
Make sure the first digit is a 0 to indicate an octal number. Do not use the mnemonic mode (e.g., +rx), because all the permissions will be turned off. |
ActivePerl supports a limited version of the chmod function. However, it can be used only for giving the owner read/write access. (The group and other bits are ignored.)
The chmod function returns the number of files that were changed.
Formatchmod(LIST); chmod LIST; Example 18.13.
|
The chown function changes the owner and group of a list of files. Only the owner or superuser can invoke it.[6] The first two elements of the list must be a numerical uid and gid. Each authorized UNIX user is assigned a uid (user identification number) and a gid (group identification number) in the password file.[7] The function returns the number of files successfully changed.
[6] On BSD UNIX and some POSIX-based UNIX (Solaris), only the superuser can change ownership.
[7] To get the uid or gid for a user, the getpwnam or getpwuid functions can be used.
Formatchown(LIST); chown LIST; Example 18.14.
|
When a file is created, it has a certain set of permissions by default. The permissions are determined by what is called the system mask. On most systems, this mask is 022 and is set by the login program.[8] A directory has 777 by default (rwxrwxrwx), and a file has 666 by default (rw-rw-rw). The umask function is used to remove or subtract permissions from the existing mask.
[8] The user can also set the umask in the .profile (sh or ksh) or .cshrc (csh) initialization files.
To take write permission away from the "others" permission set, the umask value is subtracted from the maximum permissions allowed per directory or file:
777 (directory) 666 (file)
-002 (umask value) -002 (umask value)
775 664
The umask function sets the umask for this process and returns the old one. Without an argument, the umask function returns the current setting.
Formatumask(EXPR) umask EXPR umask Example 18.15.
|
When you create a file, it has one hard link; that is, one entry in the directory. You can create additional links to the file, which are really just different names for the same file. The kernel keeps track of how many links a file has in the file's inode. As long as there is a link to the file, its data blocks will not be released to the system. The advantage to having a file with multiple names is that there is only one set of data, or master file, and that file can be accessed by a number of different names. A hard link cannot span file systems and must exist at link-creation time.
A soft link is also called a symbolic link and sometimes a symlink. A symbolic link is really just a very small file (it has permissions, ownership, size, etc.). All it contains is the name of another file. When accessing a file that has a symbolic link, the kernel is pointed to the name of the file contained in the symbolic link. For example, a link from thisfile to /usr/bin/joking/otherfile links the name thisfile to /usr/bin/joking/otherfile. When thisfile is opened, otherfile is the file really accessed. Symbolic links can refer to files that do or don't exist and can span file systems and even different computers. They can also point to other symbolic links.[9]
[9] Symbolic links originated in BSD and are supported under many ATT systems. They may not be supported on your system.
The Win32 system introduced shortcuts, special binary files with a .LNK extension. A shortcut is similar to a UNIX link, but it is processed by a particular application rather than by the system and is an alias for a file or directory. Shortcuts are icons with a little arrow in a white box in the left corner. See the Win32::Shortcut module to create, load, retrieve, save, and modify shortcut properties from a Perl script. (See Figure 18.4.)
The link function creates a hard link (i.e., two files that have the same name) on UNIX systems. The first argument to the link function is the name of an existing file; the second argument is the name of the new file, which cannot already exist. Only the superuser can create a link that points to a directory. Use rmdir when removing a directory.
Formatlink(OLDFILENAME, NEWFILENAME); Example 18.16.
|
The unlink function deletes a list of files on both UNIX and Windows systems (like the UNIX rm command or the MS-DOS del command). If the file has more than one link, the link count is dropped by 1. The function returns the number of files successfully deleted. To remove a directory, use the rmdir function, since only the superuser can unlink a directory with the unlink function.
Formatunlink (LIST); unlink LIST; Example 18.17.
|
The symlink function creates a symbolic link. The symbolic link file is the name of the file that is accessed if the old filename is referenced.
Formatsymlink(OLDFILE, NEWFILE) Example 18.18.
|
The readlink function returns the value of the symbolic link and is undefined if the file is not a symbolic link.
Formatreadlink(SYMBOLIC_LINK); readlink SYMBOLIC_LINK; Example 18.19.
|
The rename function changes the name of the file, like the UNIX mv command. The effect is to create a new link to an existing file and then delete the existing file. The rename function returns 1 for success and returns 0 for failure. This function does not work across file system boundaries. If a file with the new name already exists, its contents will be destroyed.
Formatrename(OLDFILENAME, NEWFILENAME); Example 18.20.
|
The utime function changes the access and modification times on each file in a list of files, like the UNIX touch command. The first two elements of the list must be the numerical access and modification times, in that order. The time function feeds the current time to the utime function. The function returns the number of files successfully changed. The inode modification time of each file in the list is set to the current time.
Formatutime (LIST); utime LIST; Example 18.21.
|
The information for a file is stored in a data structure called an inode, maintained by the kernel. For UNIX users, much of this information is retrieved with the ls command. In C and Perl programs, this information may be retrieved directly from the inode with the stat function. See the File::stat module, which creates a user interface for the stat function. Although the emphasis here is UNIX, the stat function also works with Win32 systems.
The stat function returns a 13-element array containing statistics retrieved from the file's inode. The last two fields, dealing with blocks, are defined only on BSD UNIX systems.[10]
[10] Wall, L., Christianson, T., and Orwant, J., Programming Perl, 3rd ed., O'Reilly & Associates: Sebastopol, CA, 2000, p. 188.
The lstat function is like the stat function, but if the file is a symbolic link, lstat returns information about the link itself rather than about the file it references. If your system does not support symbolic links, a normal stat is done.
The special underscore filehandle is used to provide stat information from the file most previously stated. The 13-element array returned contains the following elements stored in the stat structure. (The order is a little different from the UNIX system call stat.)
Device number
Inode number
Mode
Link count
User ID
Group ID
Size in bytes, for regular files
Time of last access
Time of the last modification
Time of last file status change
Preferred I/O block size for file system
Actual number of 512-byte blocks allocated
Formatstat(FILEHANDLE); stat FILEHANDLE; stat(EXPR); Example 18.22.
|
Code View: (Windows) # Since UNIX and Windows treat files differently, # some of the fields here are # blank or values returned are not meaningful 1 @stats = stat("C:\\ellie\\testing"); 2 print "Device: $stats[0]\n"; 3 print "Inode #: $stats[1]\n"; 4 print "File mode: $stats[2]\n"; 5 print "# Hard links: $stats[3]\n"; 6 print "Owner ID: $stats[4]\n"; 7 print "Group ID: $stats[5]\n"; 8 print "Device ID: $stats[6]\n"; 9 print "Total size: $stats[7]\n"; 10 print "Last access time: $stats[8]\n"; 11 print "Last modify time: $stats[9]\n"; 12 print "Last change inode time: $stats[10]\n"; 13 print "Block size: $stats[11]\n"; 14 print "Number of blocks: $stats[11]\n"; (Output) 2 Device: 2 3 Inode #: 0 4 File mode: 16895 5 # Hard links: 1 6 Owner ID: 0 7 Group ID: 0 8 Device ID: 2 9 Total size: 0 10 Last access time: 981360000 11 Last modify time: 977267374 12 Last change inode time: 977267372 13 Block size: 14 Number of blocks: |
The read function reads a specified number of bytes from a filehandle and puts the bytes in a scalar variable. If you are familiar with C's standard I/O fread function, Perl's read function handles I/O buffering in the same way. To improve efficiency, rather than reading a character at a time, a block of data is read and stored in a temporary storage area. C's fread function and Perl's read functions then transfer data, a byte at a time, from the temporary storage area to your program. (The sysread function is used to emulate C's low-level I/O read function.) The function returns the number of bytes read or an undefined value if an error occurred. If EOF (end of file) is reached, 0 is returned.
In Perl, the print function (not the write function) is used to output the actual bytes returned by the read function. Perl's print function emulates C's fwrite function.
Formatread(FILEHANDLE, SCALAR, LENGTH, OFFSET); read(FILEHANDLE, SCALAR, LENGTH); Example 18.24.
|
The sysread function is like C's read function. It bypasses the standard I/O buffering scheme and reads bytes directly from the filehandle to a scalar variable. Mixing read and sysread functions can cause problems, since the read function implements buffering, and the sysread function reads bytes directly from the filehandle.
The syswrite function writes bytes of data from a variable to a specified filehandle. It emulates C's write function.
Formatsysread(FILEHANDLE, SCALAR, LENGTH, OFFSET); sysread(FILEHANDLE, SCALAR, LENGTH); syswrite(FILEHANDLE, SCALAR, LENGTH, OFFSET); syswrite(FILEHANDLE, SCALAR, LENGTH); |
Perl's seek function is the same as the fseek standard I/O function in C. It allows you to randomly access a file. It sets a position in a file, measured in bytes from the beginning of the file, where the first byte is byte 0. The function returns 1 if successful, 0 if not.
Formatseek(FILEHANDLE, OFFSET, POSITION);
OFFSET = Number of bytes from POSITION. A positive offset advances the position forward in the file. A negative offset moves the position backward in the file. A negative OFFSET sets the file position for POSITION 1 or 2. Example 18.25.
|
The tell function returns the current byte position of a filehandle for a regular file. The position can be used as an argument to the seek function to move the file position to a particular location in the file.
Formattell (FILEHANDLE); tell FILEHANDLE; tell; Example 18.26.
|
Remember the printf and sprintf functions? They were used to format their arguments as floating point numbers, decimal numbers, strings, etc. But the pack and unpack functions take this formatting a step further. Both functions act on strings that can be represented as bits, bytes, integers, long integers, floating point numbers, etc. The format type tells both pack and unpack how to handle these strings.
The pack and unpack functions have a number of uses. These functions are used to pack a list into a binary structure and then expand the packed values back into a list. When working with files, you can use these functions to create uuencode files, relational databases, and binary files.
When working with files, not all files are text files. Some files, for example, may be packed into a binary format to save space, store images, or in a uuencoded format to facilitate sending a file through the mail. These files are not readable as is the text on this page. The pack and unpack functions can be used to convert the lines in a file from one format to another. The pack function converts a list into a scalar value that may be stored in machine memory. The template shown in Table 18.8 is used to specify the type of character and how many characters, will be formatted. For example, the string c4, or cccc, packs a list into four unsigned characters and a14 packs a list into a 14-byte ASCII string, null padded. The unpack function converts a binary formatted string into a list. The opposite of pack puts a string back into Perl format.
Template | Description |
---|---|
a | An ASCII string (null padded) |
A | An ASCII string (space padded) |
b | A bit string (low-to-high order, like vec) |
B | A bit string (high-to-low order) |
c | A signed char value |
C | An unsigned char value |
d | A double-precision float in the native format |
f | A single-precision float in the native format |
h | A hexadecimal string (low nybble first, to high) |
H | A hexadecimal string (high nybble first) |
i | A signed integer |
I | An unsigned integer |
l | A signed long value |
L | An unsigned long value |
n | A short in "network" (big-endian) order |
N | A long in "network" (big-endian) order |
p | A pointer to a null-terminated string |
P | A pointer to a structure (fixed-length string) |
q | A signed 64-bit value |
Q | An unsigned 64-bit value |
s | A signed short value (16-bit) |
S | An unsigned short value (16-bit) |
u | A uuencoded string |
v | A short in "VAX" (little-endian) order |
V | A long in "VAX" (little-endian) order |
w | A BER compressed unsigned integer in base 128, high bit first |
x | A null byte |
X | Back up a byte |
@ | Null fill to absolute position |
Format$string=pack(Template, @list ); @list = unpack(Template, $string ); Example 18.27.
|
(Script) 1 $string=pack("A15A3", "hey","you"); # ASCII string, space padded 2 print "$string"; (Output) 2 hey you Explanation
|
Code View: (The Script) #!/bin/perl # Program to uuencode a file and then uudecode it 1 open(PW, "/etc/passwd") || die "Can't open: $!\n"; 2 open(CODEDPW, ">codedpw") || die "Can't open: $!\n"; 3 while(<PW>){ 4 $uuline=pack("u*", $_); # uuencoded string 5 print CODEDPW $uuline; } close PW; close CODEDPW; 6 open(UUPW, "codedpw") || die "Can't open: $!\n"; while(<UUPW>){ 7 print; } close UUPW; print "\n\n"; 8 open(DECODED, "codedpw") || die; 9 while(<DECODED>){ 10 @decodeline = unpack("u*", $_); 11 print "@decodeline"; } (Output) 7 E<F]O=#IX.C`Z,3I3=7!E<BU5<V5R.B\Z+W5S<B]B:6XO8W-H"@`` 19&%E;6]N.G@Z,3HQ.CHO.@H` 58FEN.G@Z,CHR.CHO=7-R+V)I;CH* .<WES.G@Z,SHS.CHO.@H` :861M.G@Z-#HT.D%D;6EN.B]V87(O861M.@H` L;'`Z>#HW,3HX.DQI;F4@4')I;G1E<B!!9&UI;CHO=7-R+W-P;V]L+VQP.@H` ?<VUT<#IX.C`Z,#I-86EL($1A96UO;B!5<V5R.B\Z"@!R E=75C<#IX.C4Z-3IU=6-P($%D;6EN.B]U<W(O;&EB+W5U8W`Z"@!L M;G5U8W`Z>#HY.CDZ=75C<"!!9&UI;CHO=F%R+W- P;V]L+W5U8W!P=6)L:6,Z 5+W5S<B]L:6(O=75C<"]U=6-I8V\* J;&ES=&5N.G@Z,S<Z-#I.971W;W)K($%D;6EN.B]U<W(O;F5T+VYL<SH* ?;F]B;V1Y.G@Z-C`P,#$Z-C`P,#$Z3F]B;V1Y.B\Z"@`O I;F]A8V-E<W,Z>#HV,#`P,CHV,#`P,CI.;R!!8V-E<W,@57-E<CHO.@H` J;F]B;V1Y-#IX.C8U-3,T.C8U-3,T.E-U;D]3(#0N>"!.;V)O9'DZ+SH* M96QL:64Z>#HY- #DV.C0P.D5L;&EE(%%U:6=L97DZ+VAO;64O96QL:64Z+W5S *<B]B:6XO8W-H"@!C 11 root:x:0:1:Super-User:/:/usr/bin/csh daemon:x:1:1::/: bin:x:2:2::/usr/bin: sys:x:3:3::/: adm:x:4:4:Admin:/var/adm: lp:x:71:8:Line Printer Admin:/usr/spool/lp: smtp:x:0:0:Mail Daemon User:/: uucp:x:5:5:uucp Admin:/usr/lib/uucp: nuucp:x:9:9:uucp Admin:/var/spool/uucppublic:/usr/lib/uucp/uucico listen:x:37:4:Network Admin:/usr/net/nls: nobody:x:60001:60001:Nobody:/: noaccess:x:60002:60002:No Access User:/: nobody4:x:65534:65534:SunOS 4.x Nobody:/: ellie:x:9496:40:Ellie Quigley:/home/ellie:/usr/bin/csh Explanation
|
(The Script) #!/bin/perl 1 $ints=pack("i3", 5,-10,15); # pack into binary structure 2 open(BINARY, "+>binary" ) || die; 3 print BINARY "$ints"; 4 seek(BINARY, 0,0) || die; while(<BINARY>){ 5 ($n1,$n2,$n3)=unpack("i3", $_); 6 print "$n1 $n2 $n3\n"; } (Output) 6 5 -10 15 Explanation
|
(The Script) $str="0x123456789ABCDE ellie..."; 1 print "$str\n"; $bytes=unpack("H*",$str); # hex string (regular order) 2 print "$bytes\n"; $str2 = pack("H*", $bytes); 3 print "$str2\n"; $bytes = unpack("h*",$str); # hex string (reversed order) 4 print "$bytes\n"; $str1 = pack("h*", $bytes); 5 print"$str1\n"; (Output) 1 0x123456789ABCDE ellie... 2 3078313233343536373839414243444520656c6c69652e2e2e 3 0x123456789ABCDE ellie... 4 038713233343536373839314243444540256c6c69656e2e2e2 5 0x123456789ABCDE ellie... Explanation
|