Thursday, March 27, 2008
Handling of signals in Shell scripting..
The command arg is to be read and executed when the shell receives signal(s) sigspec। If arg is absent or -, all specified signals are reset to their original values (the values they had upon entrance to the shell)।
If arg is the null string the signal specified by each sigspec is ignored by the shell and by the commands it invokes।
If arg is not present and -p has been supplied, then the trap commands associated with each sigspec are displayed।
If no arguments are supplied or if only -p is given, trap prints the list of commands associated with each signal number।
Each sigspec is either a signal name defined in <signal.h>, or a signal number।
If a sigspec is EXIT (0) the command arg is executed on exit from the shell। If a
sigspec is DEBUG, the command arg is executed after every simple command (see SHELL GRAMMAR above)।
If a sigspec is ERR, the command arg is executed whenever a simple command has a non-zero exit status।
The ERR trap is not executed if the failed command is part of an until or while loop, part of an if statement, part of a && or || list, or if the command's return value is being inverted via !. The -l option causes the shell to print a list of signal names and their corresponding numbers। Signals ignored upon entry to the shell cannot be trapped or reset। Trapped signals are reset to their original values in a child process when it is created। The return status is false if any sigspec is invalid; otherwise trap returns true.
Wednesday, March 26, 2008
To Take Backup of Files in Linux/+
cpio {-o|--create} [-0acvABLV] [-C bytes] [-H format] [-M message] [-O [[user@]host:]archive] [-F [[user@]host:]archive] [--file=[[user@]host:]archive] [--format=format] [--message=message] [--null] [--reset-access-time] [--verbose] [--dot] [--append] [--block-size=blocks] [--dereference] [--io-size=bytes] [--quiet] [--force-local] [--rsh-command=command] [--help] [--version] <> archive]
cpio {-i|--extract} [-bcdfmnrtsuvBSV] [-C bytes] [-E file] [-H format] [-M message] [-R [user][:.][group]] [-I [[user@]host:]archive] [-F [[user@]host:]archive] [--file=[[user@]host:]archive] [--make-directories] [--nonmatching] [--preserve-modification-time] [--numeric-uid-gid] [--rename] [-t|--list] [--swap-bytes] [--swap] [--dot] [--unconditional] [--verbose] [--block-size=blocks] [--swap-halfwords] [--io-size=bytes] [--pattern-file=file] [--format=format] [--owner=[user][:.][group]] [--no-preserve-owner] [--message=message] [--force-local] [--no-absolute-filenames] [--sparse] [--only-verify-crc] [--quiet] [--rsh-command=command] [--help] [--version] [pattern...] [< archive]
cpio {-p|--pass-through} [-0adlmuvLV] [-R [user][:.][group]] [--null] [--reset-access-time] [--make-directories] [--link] [--quiet] [--preserve-modification-time] [--unconditional] [--verbose] [--dot] [--dereference] [--owner=[user][:.][group]] [--no-preserve-owner] [--sparse] [--help] [--version] destination-directory < name-list
cpio copies files into or out of a cpio or tar archive, which is a file that contains other files plus information about them, such as their file name, owner, timestamps, and access permissions. The archive can be another file on the disk, a magnetic tape, or a pipe. cpio has three operating modes.
In copy-out mode, cpio copies files into an archive. It reads a list of filenames, one per line, on the standard input, and writes the archive onto the standard output. A typical way to generate the list of filenames is with the find command; you should give find the -depth option to minimize problems with permissions on directories that are unwritable or not searchable.
In copy-in mode, cpio copies files out of an archive or lists the archive contents. It reads the archive from the standard input. Any non-option command line arguments are shell globbing patterns; only files in the archive whose names match one or more of those patterns are copied from the archive. Unlike in the shell, an initial `.' in a filename does match a wildcard at the start of a pattern, and a `/' in a filename can match wildcards. If no patterns are given, all files are extracted.
In copy-pass mode, cpio copies files from one directory tree to another, combining the copy-out and copy-in steps without actually using an archive. It reads the list of files to copy from the standard input; the directory into which it will copy them is given as a non-option argument.
cpio supports the following archive formats: binary, old ASCII, new ASCII, crc, HPUX binary, HPUX old ASCII, old tar, and POSIX.1 tar. The binary format is obsolete because it encodes information about the files in a way that is not portable between different machine architectures. The old ASCII format is portable between different machine architectures, but should not be used on file systems with more than 65536 i-nodes. The new ASCII format is portable between different machine architectures and can be used on any size file system, but is not supported by all versions of cpio; currently, it is only supported by GNU and Unix System V R4. The crc format is like the new ASCII format, but also contains a checksum for each file which cpio calculates when creating an archive and verifies when the file is extracted from the archive. The HPUX formats are provided for compatibility with HPUX's cpio which stores device files differently.
The tar format is provided for compatability with the tar program. It can not be used to archive files with names longer than 100 characters, and can not be used to archive "special" (block or character devices) files. The POSIX.1 tar format can not be used to archive files with names longer than 255 characters (less unless they have a "/" in just the right place).
By default, cpio creates binary format archives, for compatibility with older cpio programs. When extracting from archives, cpio automatically recognizes which kind of archive it is reading and can read archives created on machines with a different byte-order.
OPTIONS
-0, --null
In copy-out and copy-pass modes, read a list of filenames terminated by a null character instead of a newline, so that files whose names contain newlines can be archived. GNU find is one way to produce a list of null-terminated filenames.
-a, --reset-access-time
Reset the access times of files after reading them, so that it does not look like they have just been read.
-A, --append
Append to an existing archive. Only works in copy-out mode. The archive must be a disk file specified with the -O or -F (--file) option.
-b, --swap
In copy-in mode, swap both halfwords of words and bytes of halfwords in the data. Equivalent to -sS. Use this option to convert 32-bit integers between big-endian and little-endian machines.
-B
Set the I/O block size to 5120 bytes. Initially the block size is 512 bytes.
--block-size=BLOCK-SIZE
Set the I/O block size to BLOCK-SIZE * 512 bytes.
-c
Identical to "-H newc", use the new (SVR4) portable format. If you wish the old portable (ASCII) archive format, use "-H odc" instead.
-C IO-SIZE, --io-size=IO-SIZE
Set the I/O block size to IO-SIZE bytes.
-d, --make-directories
Create leading directories where needed.
-E FILE, --pattern-file=FILE
In copy-in mode, read additional patterns specifying filenames to extract or list from FILE. The lines of FILE are treated as if they had been non-option arguments to cpio.
-f, --nonmatching
Only copy files that do not match any of the given patterns.
-F, --file=archive
Archive filename to use instead of standard input or output. To use a tape drive on another machine as the archive, use a filename that starts with `HOSTNAME:'. The hostname can be preceded by a username and an `@' to access the remote tape drive as that user, if you have permission to do so (typically an entry in that user's `~/.rhosts' file).
--force-local
With -F, -I, or -O, take the archive file name to be a local file even if it contains a colon, which would ordinarily indicate a remote host name.
-H FORMAT, --format=FORMAT
Use archive format FORMAT. The valid formats are listed below; the same names are also recognized in all-caps. The default in copy-in mode is to automatically detect the archive format, and in copy-out mode is "bin".
bin
The obsolete binary format.
odc
The old (POSIX.1) portable format.
newc
The new (SVR4) portable format, which supports file systems having more than 65536 i-nodes.
crc
The new (SVR4) portable format with a checksum added.
tar
The old tar format.
ustar
The POSIX.1 tar format. Also recognizes GNU tar archives, which are similar but not identical.
hpbin
The obsolete binary format used by HPUX's cpio (which stores device files differently).
hpodc
The portable format used by HPUX's cpio (which stores device files differently).
-i, --extract
Run in copy-in mode.
-I archive
Archive filename to use instead of standard input. To use a tape drive on another machine as the archive, use a filename that starts with `HOSTNAME:'. The hostname can be preceded by a username and an `@' to access the remote tape drive as that user, if you have permission to do so (typically an entry in that user's `~/.rhosts' file).
-k
Ignored; for compatibility with other versions of cpio.
-l, --link
Link files instead of copying them, when possible.
-L, --dereference
Dereference symbolic links (copy the files that they point to instead of copying the links).
-m, --preserve-modification-time
Retain previous file modification times when creating files.
-M MESSAGE, --message=MESSAGE
Print MESSAGE when the end of a volume of the backup media (such as a tape or a floppy disk) is reached, to prompt the user to insert a new volume. If MESSAGE contains the string "%d", it is replaced by the current volume number (starting at 1).
-n, --numeric-uid-gid
In the verbose table of contents listing, show numeric UID and GID instead of translating them into names. Also extracts tar archives using the numeric UID and GID instead of the user/group names. (cpio archives are always extracted using the numeric UID and GID.)
--no-absolute-filenames
In copy-in mode, create all files relative to the current directory, even if they have an absolute file name in the archive.
--no-preserve-owner
In copy-in mode and copy-pass mode, do not change the ownership of the files; leave them owned by the user extracting them. This is the default for non-root users, so that users on System V don't inadvertantly give away files.
-o, --create
Run in copy-out mode.
-O archive
Archive filename to use instead of standard output. To use a tape drive on another machine as the archive, use a filename that starts with `HOSTNAME:'. The hostname can be preceded by a username and an `@' to access the remote tape drive as that user, if you have permission to do so (typically an entry in that user's `~/.rhosts' file).
--only-verify-crc
When reading a CRC format archive in copy-in mode, only verify the CRC's of each file in the archive, don't actually extract the files.
-p, --pass-through
Run in copy-pass mode.
--quiet
Do not print the number of blocks copied.
-r, --rename
Interactively rename files.
-R [user][:.][group], --owner [user][:.][group]
In copy-out and copy-pass modes, set the ownership of all files created to the specified user and/or group. Either the user or the group, or both, must be present. If the group is omitted but the ":" or "." separator is given, use the given user's login group. Only the super-user can change files' ownership.
--rsh-command=COMMAND
Notifies mt that it should use COMMAND to communicate with remote devices instead of /usr/bin/ssh or /usr/bin/rsh.
--sparse
In copy-in and copy-pass modes, write files with large blocks of zeros as sparse files.
-s, --swap-bytes
In copy-in mode, swap the bytes of each halfword (pair of bytes) in the files.
-S, --swap-halfwords
In copy-in mode, swap the halfwords of each word (4 bytes) in the files.
-t, --list
Print a table of contents of the input.
-u, --unconditional
Replace all files, without asking whether to replace existing newer files with older files.
-v, --verbose
List the files processed, or with -t, give an `ls -l' style table of contents listing. In a verbose table of contents of a ustar archive, user and group names in the archive that do not exist on the local system are replaced by the names that correspond locally to the numeric UID and GID stored in the archive.
-V --dot
Print a "." for each file processed.
--version
Print the cpio program version number and exit.
Wednesday, March 12, 2008
Parsing arguments for your shell script
Suppose you want to have some options on your bash shell script, some flags that you can use to alter its behavior. You could do the parsing directly, using ${#} to tell you how many arguments have been supplied, and testing ${1:0:1} to test the first character of the first argument to see if it is a minus sign. You would need some if/then or case logic to identify which option it is and whether it takes an argument. What if the user doesn't supply a required argument? What if the user calls your script with two options combined (e.g., -ab)? Will you also parse for that? The need to parse options for a shell script is a common situation. Lots of scripts have options. Isn't there a more standard way to do this?
This article is excerpted from the newly published book bash Cookbook.
The solution -- use bash's built-in getopts command to help parse options. Here is an example, based largely on the example in the manpage for getopts
#!/usr/bin/env bash
# cookbook filename: getopts_example
#
# using getopts
#
aflag=
bflag=
while getopts 'ab:' OPTION
do
case $OPTION in
a) aflag=1
;;
b) bflag=1
bval="$OPTARG"
;;
?) printf "Usage: %s: [-a] [-b value] args\n" $(basename $0) >&2
exit 2
;;
esac
done
shift $(($OPTIND - 1))
if [ "$aflag" ]
then
printf "Option -a specified\n"
fi
if [ "$bflag" ]
then
printf 'Option -b "%s" specified\n' "$bval"
fi
printf "Remaining arguments are: %s\n" "$*"
There are two kinds of options supported here. The first and simpler kind is an option that stands alone. It typically represents a flag to modify a command's behavior. An example of this sort of option is the -l option on the ls command. The second kind of option requires an argument. An example of this is the mysql command's -u option, which requires that a username be supplied, as in mysql -u sysadmin. Let's look at how getopts supports the parsing of both kinds.
The use of getopts has two arguments.
getopts 'ab:' OPTION
The first is a list of option letters. The second is the name of a shell variable. In our example, we are defining -a and -b as the only two valid options, so the first argument in getopts has just those two letters -- and a colon. What does the colon signify? It indicates that -b needs an argument, just like -u username or -f filename might be used. The colon needs to be adjacent to any option letter taking an argument. For example, if only -a took an argument we would need to write 'a:b' instead.
The getopts built-in will set the variable named in the second argument to the value that it finds when it parses the shell script's argument list ($1, $2, etc.). If it finds an argument with a leading minus sign, it will treat that as an option argument and put the letter into the given variable ($OPTION in our example). Then it returns true (i.e., 0) so that the while loop will process the option then continue to parse options by repeated calls to getopts until it runs out of arguments (or encounters a double minus -- to allow users to put an explicit end to the options). Then getopts returns false (i.e., non-zero) and the while loop ends.
Inside the loop, when the parsing has found an option letter for processing, we use a case statement on the variable $OPTION to set flags or otherwise take action when the option is encountered. For options that take arguments, that argument is placed in the shell variable $OPTARG (a fixed name not related to our use of $OPTION as our variable). We need to save that value by assigning it to another variable because as the parsing continues to loop, the variable $OPTARG will be reset on each call to getopts.
The third case of our case statement is a question mark, a shell pattern that matches any single character. When getopts finds an option that is not in the set of expected options ('ab:' in our example) then it will return a literal question mark in the variable ($OPTION in our example). So we could have made our case statement read \?) or '?') for an exact match, but the ? as a pattern match of any single character provides a convenient default for our case statement. It will match a literal question mark as well as matching any other single character.
In the usage message that we print, we have made two changes from the example script in the manpage. First, we use $(basename $0) to give the name of the script without all the extra pathnames that may have been part of how it was invoked. Secondly, we redirect this message to standard error (>&2) because that is really where such messages belong. All of the error messages from getopts that occur when an unknown option or missing argument is encountered are always written to standard error. We add our usage message to that chorus.
When the while loop terminates, we see the next line to be executed is:
shift $(($OPTIND - 1))
which is a shift statement used to move the positional parameters of the shell script from $1, $2, etc. down a given number of positions (tossing the lower ones). The variable $OPTIND is an index into the arguments that getopts uses to keep track of where it is when it parses. Once we are done parsing, we can toss all the options that we've processed by doing this shift statement. For example, if we had this command line:
myscript -a -b alt plow harvest reap
then after parsing for options, $OPTIND would be set to 4. By doing a shift of three ($OPTIND-1) we would get rid of the options and then a quick echo$* would give this:
plow harvest reap
So, the remaining (non-option) arguments are ready for use in your script (in a for loop perhaps). In our example script, the last line is a printf showing all the remaining arguments.
Tuesday, March 04, 2008
How to Select Columns From a File?
Consider a slight variation on the company.data file we've been playing with in this section:
406378:Sales:Itorre:Jan
031762:Marketing:Nasium:Jim
636496:Research:Ancholie:Mel
396082:Sales:Jucacion:Ed
If you want to print just columns 1 to 6 of each line (the employee serial numbers), use the -c1-6 flag, as in this command:
cut -c1-6 company.data
406378
031762
636496
396082
If you want to print just columns 4 and 8 of each line (the first letter of the department and the fourth digit of the serial number), use the -c4,8 flag, as in this command:
cut -c4,8 company.data
3S
7M
4R
0S
And since this file obviously has fields delimited by colons, we can pick out just the last names by specifying the -d: and -f3 flags, like this:
cut -d: -f4,3 company.data
Itorre
Nasium
Ancholie
Jucacion
Here is a summary of the most common flags for the cut command:
-c [n | n,m | n-m] Specify a single column, multiple columns (separated by a comma), or range of columns (separated by a dash).
-f [n | n,m | n-m] Specify a single field, multiple fields (separated by a comma), or range of fields (separated by a dash).
-dc Specify the field delimiter.
-s Suppress (don't print) lines not containing the delimiter.