Monday, November 24, 2008

How to group UNIX Solaris, Linux commands

Simply group them in a small bracket and separate them by semi colon (;)

123-bash: (ls -1;pwd;cd /tmp/curl)

It will list the files in CWD first, print the directory you are in, cd to /tmp/curl

Tuesday, November 18, 2008

How to get user input in PERL

It's simple -

- The angle bracket operator to read from STDIN (see I/O operators in perlop)
- If entering 'Y' or 'N' - make sure to use 'chomp' to cut the new line character.
- @ARGV - the array that holds parameters from the command line (see perlvar)
- Getopt::Long or Getopt::Std - for more powerful handling of command line arguments
- uc - to uppercase an expression
- ucfirst - to uppercase the first letter of an expression

Later in your code, you can compare by using 'eq' or 'ne' or '==' or '!=' or
pattern matching =~ m///, thingy to move on to do what you want.....

Friday, November 14, 2008

Solaris Kernel Modules operations

Kernel Modules:
---------------

modinfo : prints out information on all currently loaded kernel modules.
modload : loads kernel modules.
modunload : unloads kernel modules.
forceload : in the /etc/system file loads a module at boot time.

Monday, November 10, 2008

Passing a DB handler to an user defined function

It is pretty simply. Pass it like an ordinary variable.

Example here:

#!/opt/local/bin/perl

use db_connect;
use warnings;
use strict;


# More efficient than ./test_connection.pl because $0 makes only one DB connection

my $obj = db_connect->new();
my $db = $obj->connect_qora007_mir("qora007_mir");

print " \n";
&checkConnectionMIR_qora007($db);
&checkConnectionCIR_qora007($db);
print " \n";

$db->disconnect();



sub checkConnectionMIR_qora007($)
{
my $dbh = shift;

my $sql;
my $sth;
my $str;
my @row;

$sql = "select sysdate from dual";

$sth = $dbh->prepare($sql);
$sth->execute;

while((@row) = $sth->fetchrow_array())
{
$str = join(" " , map {defined $_ ? $_ : "(null)"} @row);
print "INSTANCE: $str\n";
}

Thursday, November 6, 2008

PERL - IF ELSE statement shortcuts

I will give an example of how to write IF ELSE statement in short. This will be simply useful to read others code if you know that this can also be an option. This kind of code normally comes from seasoned PERL programers.

#!/opt/local/bin/perl

use warnings;
use strict;

print &max(5, 3);
print &max(7, 10);

sub max (@)
{
my ($x, $y) = @_;
return $x > $y ? $x : $y;
}

Explanation: In function max, 2nd lines means that

if $x is greater than $y, return $x or return $y. That's it.....

Wednesday, November 5, 2008

How to open a write into an already zipped file in perl:

How to open a write into an already zipped file in perl:
--------------------------------------------------------

my $temp_file = "file_name.gz";
open(HWRITE, "|gzip -c > $temp_file") or die "cannot open file $temp_file\n";
print HWRITE "Something_1|Something_1|Something_1|Something_1\n"
or die "File write failed : $!\n";

Friday, October 10, 2008

How to pass an object in a function

It is really simple concept but can confuse novice to perl. An object can be passed to a function just like an ordinary variable. File handler need special syntax to be
passed inside a function but not an object.

Follow this simple example here. Code is incomplete but is tested when complete.

Here it goes:

#!/opt/local/bin/perl

use lib "$ENV{HOME}/perl/lib";
use convert_time;
use dir_pool;
use db_connect;
use warnings;
use strict;

my $obj = db_connect->new();

&doConnectMIR($obj);
print " \n";
&doConnectCIR($obj);


sub doConnectMIR($)
{
my $tObj = shift;

my $dbh;
my $sql;
my $sth;
my $str;
my @row;

$tObj = db_connect->new();
$dbh = $obj->connect_qora007_mir("qora007_mir");

$sql = "select sysdate from dual";

$sth = $dbh->prepare($sql);
$sth->execute;

while((@row) = $sth->fetchrow_array())
{
$str = join(" " , map {defined $_ ? $_ : "(null)"} @row);
print "INSTANCE: $str\n";
}


more code follows.....but concept is clear.....

Wednesday, August 20, 2008

Typical Oracle profile file on Unix

# .oracle10g


### Oracle specific setup
ORACLE_HOME=/opt/oracle10g/instantclient_10_2
TNS_ADMIN=/opt/oracle10g/instantclient_10_2
NLS_LANG=_.WE8ISO8859P1

export ORACLE_HOME TNS_ADMIN NLS_LANG


LD_LIBRARY_PATH=$ORACLE_HOME:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
PATH=$ORACLE_HOME:$PATH

export PATH
### End Oracle specific setup

Typical Oracle profile file on Unix

# .oracle10g


### Oracle specific setup
ORACLE_HOME=/opt/oracle10g/instantclient_10_2
TNS_ADMIN=/opt/oracle10g/instantclient_10_2
NLS_LANG=_.WE8ISO8859P1

export ORACLE_HOME TNS_ADMIN NLS_LANG


LD_LIBRARY_PATH=$ORACLE_HOME:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
PATH=$ORACLE_HOME:$PATH

export PATH
### End Oracle specific setup

Friday, August 1, 2008

Perl Internals - Simon Cozens

http://www.faqs.org/docs/perl5int/

How Hashes Really Work

Great article to understand Hashes in PERL

Thursday, July 24, 2008

PERL - How to use %INC & @INC on command line

perl -e 'use XML::Simple;use XML::Parser; foreach my $tuni (keys %INC){print $tuni . "\t" . $INC{$tuni} . "\n"}'

perl -e 'print "@INC\n"'

Multiple -e can be used, just like shell's sed program.

Wednesday, July 9, 2008

Unix - Large file aware utilities

A large file is a regular file whose size is greater than or
equal to 2 Gbyte ( 2**31 bytes). A small file is a regular
file whose size is less than 2 Gbyte.

Large file aware utilities
A utility is called large file aware if it can process large
files in the same manner as it does small files. A utility
that is large file aware is able to handle large files as
input and generate as output large files that are being pro-
cessed. The exception is where additional files are used as
system configuration files or support files that can augment
the processing.

For example, the file utility supports the
-m option for an alternative "magic" file and the -f option
for a support file that can contain a list of file names. It
is unspecified whether a utility that is large file aware
will accept configuration or support files that are large
files. If a large file aware utility does not accept confi-
guration or support files that are large files, it will
cause no data loss or corruption upon encountering such
files and will return an appropriate error.



The following /usr/bin utilities are large file aware:

adb awk bdiff cat chgrp
chmod chown cksum cmp compress
cp csh csplit cut dd
dircmp du egrep fgrep file
find ftp getconf grep gzip
head join jsh ksh ln
ls mdb mkdir mkfifo more
mv nawk page paste pathchck
pg rcp remsh rksh rm
rmdir rsh sed sh sort
split sum tail tar tee
test touch tr uncompress uudecode
uuencode wc zcat



The following /usr/xpg4/bin utilities are large file aware:

awk cp chgrp chown du
egrep fgrep file grep ln
ls more mv rm sed
sh sort tail tr


The following /usr/sbin utilities are large file aware:

install mkfile mknod mvdir swap

Wednesday, July 2, 2008

Knowledge about pixel, resolution and how to convert pixel into inches

Folks,
Recently I got to work with GD library using PHP 5.xx and was little confused about pixels, resolution and how to convert them into physical dimensional measurement units like centimeters or inches.

I think, lots of people are still very confused about it but still work as developers in GUI or web development.

Here is some information......

Say, there is an image of a flower 400x300 pixels. It means that height of this image is 400 pixel and width is 300 pixels. With it, there must be one more attribute of screen called 'resolution' (Remember, your color TV resolution).
Say that is 72 ppi (pixel per inch).

Simple mathematics: 72 ppi means
72 pixels in 1 inch
Therefore, 400 pixels in = 400/72 = 5.55 inches tall
Therefore, 300 pixels in = 300/72 = 4.16 inches wide

Hope it clears the cloud.

Tuesday, July 1, 2008

How to convert seconds into HH:MM:SS (24 hour format)

// $startstamp, $endstamp are both UNIX timestamp
// from Jan 1, 1970 mid night

function elapsed_time($startstamp, $endstamp)
{
$sec=$endstamp - $startstamp;

$hours = ($sec/3600);
list($hours, $x) = split('\.', $hours);
if ($hours < 10)
{
$hours = "0" . $hours;
}

$min = ($sec%3600);
$min = ($min/60);
list($min, $x) = split('\.', $min);
if ($min < 10)
{
$min = "0" . $min;
}

$sec = ($sec%60);
if ($sec < 10)
{
$sec = "0" . $sec;
}

return "$hours:$min:$sec";

}

Thursday, June 19, 2008

MySQL - Convert MySQL date, datetime, timestamp to unix time and Vice versa

&& To convert Unix time to regular MySQL DATETIME
select from_unixtime('1213907115');
It prints '2008-06-19 16:25:15'


&& To Convert DATETIME to unixtime
select unix_timestamp('2008-06-19 16:25:15');
It prints 1213907115


&& To Convert current date & time to unix time.
select unix_timestamp();


&& To Convert a column of DATETIME type to unixtime.
select unix_timestamp(c8013_date_created) from RealTimeStatus.T8013_PROGRAM;

Thursday, June 12, 2008

PERL - Hash, Hash reference and file handler passing to a subroutines

Fews days ago - One of my friends asked me about:
1. hashes in perl
2. hash references and how to use them
3. file handler passing to a subroutines....

Here is an example.....


#!/opt/local/bin/perl

use warnings;
use strict;

my $n_ref;
my $p_ref;


open(NAME, "./tns_names") or die " Failed to open tns_names file : $! \n ";
open(PASS, "./tns_pass") or die " Failed to open tns_pass file : $! \n ";

$n_ref = &process_names(*NAME);
$p_ref = &process_pass(*PASS);

&do_final($n_ref, $p_ref);

close NAME;
close PASS;


sub process_names($)
{
local *h = shift;

my %n;
my $nkey;
my $nval;

while()
{
chomp $_;
($nkey, $nval) = split(/,/, $_);
$n{$nkey} = $nval;
}
return \%n;
}


sub process_pass($)
{
local *h = shift;

my %p;
my $pkey;
my $pval;

while()
{
chomp $_;
($pkey, $pval) = split(/,/, $_);
$p{$pkey} = $pval;
}
return \%p;
}


sub do_final(@)
{
my ($nam, $pas) = @_;
my $akey;

foreach $akey (keys %$nam)
{
print 'Key :' . $akey . ' and Value: ' . $nam->{$akey} . "\n";
}

foreach $akey (keys %$pas)
{
print 'Key :' . $akey . ' and Value: ' . $pas->{$akey} . "\n";
}
}


1;

PERL - I/O Redirection Example

The following example shows how I/O can be simply redirected:

open(F, '>/tmp/x') || die;
*STDOUT = *F;
print "hello world\n";

The print function thinks it is sending the output to STDOUT but ends up sending it to the open file instead, because the typeglob associated with STDOUT has been aliased to F. If you want this redirection to be temporary, you can localize *STDOUT.

PERL - Passing Filehandles to Subroutines

#!/usr/bin/perl
use warnings;
use strict;

open(NAME, "./names") or die " Failed to open tns_names file : $! \n ";
open(PASS, "./pass") or die " Failed to open tns_pass file : $! \n ";

&process_names(*NAME);
&process_pass(*PASS);

close NAME;
close PASS;


sub process_names($)
{
local (*h) = shift;
while()
{
chomp $_;
print $_ . "\n";
}

}


sub process_pass($)
{
local (*h) = shift;
while()
{
chomp $_;
print $_ . "\n";
}
}

Friday, June 6, 2008

How to install ‘mysql-server’ community 5.1 and client on RHEL 5.0

How to install ‘mysql-server’ community 5.1 and client on RHEL 5.0

Step 1:

First step is to check if there are any version of mysql already installed. This is due to the fact that RHEL has some default packages available already. Do this.

rpm –qa |grep mysql
mysql-connector-odbc-3.51.12-2.2
MySQL-python-1.2.1-1
mysql-5.0.45-7.el5
perl-DBD-MySQL-3.0007-1.fc6
libdbi-dbd-mysql-0.8.1a-1.2.2
mysql-server-5.0.45-7.el5

Printed are a list of mysql server installed, clients and drivers like perl DBD driver, python driver and other stuff. Best idea is to get rid of all these dependencies and build it again. That can be done by

rpm –e < mysql-server-5.0.45-7.el5>
rpm –e < libdbi-dbd-mysql-0.8.1a-1.2.2
…..and so on.


Step 2:

Try installing MySQL server 5.1 from MySQL mirror website itself. It would automatically start the server once successfully installed. ‘root’ is the default user id with a blank password. Root’s password can be changed once client package is installed which includs mysql and mysqladmin and other administrative tools.

rpm –i http://dev.mysql.com/get/Downloads/MySQL-5.1/MySQL-server-community-5.1.24-0.rhel5.i386.rpm/from/http://mirror.trouble-free.net/mysql_mirror/


Step 3:

Try installing MySQL clients packages which include administrative tools like mysql, mysqladmin, mysqldump and others…..

rpm –i http://dev.mysql.com/get/Downloads/MySQL-5.1/MySQL-client-community-5.1.24-0.rhel5.i386.rpm/from/http://mirror.trouble-free.net/mysql_mirror/

Step 4:

Change root user password or simply execute /usr/bin/mysql_secure_installation. Answer all the questions appropriately. That’s it.

Step 5:

Check if mysql is running by doing: ps –eaf|grep mysqld

Also try connecting to it by doing.
mysql –uroot –p
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 38
Server version: 5.1.24-rc-community MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| mysqlDB |
| test |
+--------------------+
4 rows in set (0.00 sec)

====== Now, you are all set =====================

DO NOT FORGET TO RE-INSTALL DRIVERS FOR CLIENTS LIKE PERL, PYTHON, PHP.

How to install 'MySQL' driver on Solaris platform

How to install 'MySQL' driver on Solaris platform:
-------------------------------------------------

STEP 1:

Download DBD-mysql-4.007.tar.gz http://search.cpan.org/dist/DBD-mysql/lib/DBD/mysql.pm
by using wget tool from unix10/unix22 boxes because ftp/telnet/scp/sftp is prohibited.

STEP 2:

Copy this file into /tmp/mysql ( Create a temporary directory mysql under /tmp )

STEP 3:

gzip -d DBD-mysql-4.007.tar.gz

STEP 4:

tar xvf DBD-mysql-4.007.tar

STEP 5:

cd DBD-mysql-4.007


STEP 6:

perl Makefile.PL --libs="-L/usr/local/mysql/lib/mysql -lmysqlclient -lz" \
--cflags=-I/usr/local/mysql/include/mysql

STEP 7:

make
make install


STEP 8: mysql driver has been installed if 'make install' does not produce any errors.


STEP 9: How to verify if - mysql driver is installed.

Used this perl script to verify:

#!/opt/local/bin/perl -w

use strict;
use DBI;

$|=1;
my @x_drivers = DBI->available_drivers();
foreach (@x_drivers){ print $_ . "\n";}

__END__

How to install mtop for MySQL on RHEL 5.0 machine

How to install mtop for MySQL on RHEL 5.0 machine:

Step 1: Download
wget http://downloads.sourceforge.net/mtop/mtop0.6.6.tar.gz?modtime=1094947200&big_mirror=0

Step 2: unzip it.
gzip -d mtop-0.6.6.tar.gz

Step 3: Extract the files
tar xvf mtop-0.6.6.tar

NOTE: It will create a directory named ‘mtop-0.6.6’

Step 4: Install it.
mtop-0.6.6
perl Makefile.PL
sudo make
sudo make install


mtop is installed. If ‘which mtop’ is done, it will print
/usr/local/bin/mtop

Thursday, June 5, 2008

Where to download mtop from - if unix/linux boxes can not connect to your windows

Folks,

For most of us, Unix/Linux (Dev/QA) environment is totally separate from our work machine which should be most likely windows boxes and basically users use putty, or something like that. What if network does not allow you to copy or ftp/sftp
anything from your windows box to Unix/Linux boxes.

Simply use this on your unix machine:
wget http://search.cpan.org/CPAN/authors/id/M/MP/MPREWITT/mtop/mtop-0.6.4.tar.gz

Convert character sets from UTF8 to Latin1 and Base64

Folks,
I came across this learning during some work where I have to convert some utf8 based characters from database to latin1 and some cases vice versa.....

Perl site has good demo of this. Check this out...

http://perldoc.perl.org/Encode/Encoder.html.

This can also convert Latin1 to base64 and vice versa....

Pretty cool stuff.

Thursday, May 29, 2008

How to know, which all DBD exists on a Unix/Linux platform

#!/opt/local/bin/perl

## How to know, which all DBD exists on a Unix/Linux platform.

use warnings;
use strict;
use DBI;

my @xt=DBI->available_drivers();
foreach (@xt)
{
print $_ . "\n";
}

Wednesday, May 28, 2008

UNIX shell differences and how to change your shell

The following article answers the frequently asked questions, what
UNIX shells are available, what are the differences between them and
how do you change your interactive shell. It is posted monthly to the
USENET newsgroups comp.unix.shell, comp.unix.questions, news.answers
and comp.answers and is additionally available on the world wide web
as http://www.wonderland.org/~eternal/shell.html

Contents

* Modifications since last issue
* Why change your shell
* The history of unix shells
* Deciding on a shell
* Shell features (table)
* How to change your shell
* A warning about changing your shell
* Further information
* Copyright and Disclaimer

Modifications since last issue

* Change of authors contact addresses

Why change your shell

The UNIX shell is most people's main access to the UNIX operating
system and as such any improvement to it can result in considerably
more effective use of the system, and may even allow you to do things
you couldn't do before. The primary improvement most of the new
generation shells give you is increased speed. They require fewer key
strokes to get the same results due to their completion features, they
give you more information (e.g. showing your directory in your prompt,
showing which files it would complete) and they cover some of the more
annoying features of UNIX, such as not going back up symbolic links to
directories.

A brief history of UNIX shells

Note, this history is just known to be slightly out of historical
order, it is in the process of being corrected, but for the moment
should be taken with a pinch of salt

In the near beginning there was the Bourne shell /bin/sh (written by
S. R. Bourne). It had (and still does) a very strong powerful
syntactical language built into it, with all the features that are
commonly considered to produce structured programs; it has
particularly strong provisions for controlling input and output and in
its expression matching facilities. But no matter how strong its input
language is, it had one major drawback; it made nearly no concessions
to the interactive user (the only real concession being the use of
shell functions and these were only added later) and so there was a
gap for something better.

Along came the people from UCB and the C-shell /bin/csh was born. Into
this shell they put several concepts which were new, (the majority of
these being job control and aliasing) and managed to produce a shell
that was much better for interactive use. But as well as improving the
shell for interactive use they also threw out the baby with the bath
water and went for a different input language.

The theory behind the change was fairly good, the new input language
was to resemble C, the language in which UNIX itself was written, but
they made a complete mess of implementing it. Out went the good
control of input and output and in came the bugs. The new shell was
simply too buggy to produce robust shell scripts and so everybody
stayed with the Bourne shell for that, but it was considerably better
for interactive use so changed to the C shell, this resulted in the
stupid situation where people use a different shell for interactive
work than for non-interactive, a situation which a large number of
people still find themselves in today.

After csh was let loose on an unsuspecting world various people
decided that the bugs really should get fixed, and while they where at
it they might as well add some extra features. In came command line
editing, TENEX-style completion and several other features. Out went
most of the bugs, but did the various UNIX operating system
manufacturers start shipping tcsh instead of csh? No, most of them
stuck with the standard C-Shell, adding non-standard features as they
went along.

Eventually David Korn from AT&T had the bright idea to sort out this
mess and the Korn shell /bin/ksh made its appearance. This quite
sensibly junked the C shells language and reverted back to the bourne
shell language, but it also added in the many features that made the C
shell good for interactive work (you could say it was the best of both
worlds), on top of this, it also added a some features from other
operating. The Korn shell became part of System V but had one major
problem; unlike the rest of the UNIX shells it wasn't free, you had to
pay AT&T for it.

It was at about this time that the first attempts to standardize UNIX
started in the form of the POSIX standard. POSIX specified more or
less the System V Bourne Shell (by this time the BSD and System V
versions had got slightly different). Later the standard is upgraded,
and somehow the new standard managed to look very much like ksh.

Also at about this time the GNU project was underway and they decided
that they needed a free shell, they also decided that they wanted to
make this new shell POSIX compatible, thus bash (the Bourne again
shell) was born. Like the Korn shell bash was based upon the Bourne
shells language and like the Korn shell, it also pinched features from
the C shell and other operating systems (in my opinion it put them
together better; guess which shell I use), but unlike the Korn shell
it is free. Bash was quickly adopted for LINUX (where it can be
configured to perform just like the Bourne shell), and is the most
popular of the free new generation shells.

Meanwhile Tom Duff faced with the problem of porting the Bourne shell
to Plan 9, revolts and writes rc instead, he publishes a paper on it,
and Byron Rakitzis reimplements it under UNIX. With the benefit of a
clean start Rc ended up smalled, simpler, more regular and in most
peoples opinion a much cleaner shell.

The search for the perfect shell still goes on and the latest entry
into this arena is zsh. Zsh was written by Paul Falstad while he was a
student a Princeton and suffers from slight case of feeping
creaturism. It is based roughly on the bourne shell (although there
are some minor but important differences) and has so many additional
features that I don't even think the author even knows all of them.

Additionally rc has been enhanced to produced es, this shell adds the
ability for the user to redefine low level functions.

Deciding on a shell

Which of the many shells you choose depends on many different things,
here is what I consider to be the most important, you may think
differently.

How much time do I have to learn a new shell?
There is no point in using a shell with a different syntax, or
a completly different alias system if you havn't the time to
learn it. If you have the time and are presently using csh or
tcsh it is worth considering a switch to a Bourne shell
variant.

What do I wish to be able to do with my new shell?
The main reason for switching shells is to gain extra
functionality; its vital you know what you are gaining from the
switch.

Do I have to be able to switch back to a different shell?
If you may have to switch back to a standard shell, it is
fairly important you don't become too dependent on extra
features and so can't use an older shell.

How much extra load can the system cope with?
The more advanced shells tend to take up extra CPU, since they
work in cbreak mode; if you are on an overloaded machine they
should probably be avoided; this can also cause problems with
an overloaded network. This only really applies to very old
systems nowadays.

What support is given for my new shell?
If your new shell is not supported make sure you have someone
you can ask if you encounter problems or that you have the time
to sort them out yourself.

What shell am I using already?
Switching between certain shells of the same syntax is alot
easier than switching between shells of a different syntax. So
if you havn't much time a simple upgrade (eg csh to tcsh) may
be a good idea.

Can I afford any minor bugs?
Like most software all shells have some bugs in them
(especially csh), can you afford the problems that may occur
because of them.

Do you need to be able to use more than one shell?
If you use more than one machine you may discover that you need
to use more than one shell regularly. How different are these
shells and can you cope with having to switch between these
shells on a regular basis. It may be to your advantage to
choose shells that are similar to each other.

Shell features

This table below lists most features that I think would make you
choose one shell over another. It is not intended to be a definitive
list and does not include every single possible feature for every
single possible shell. A feature is only considered to be in a shell
if in the version that comes with the operating system, or if it is
available as compiled directly from the standard distribution. In
particular the C shell specified below is that available on SUNOS 4.*,
a considerable number of vendors now ship either tcsh or their own
enhanced C shell instead (they don't always make it obvious that they
are shipping tcsh.

sh csh ksh bash tcsh zsh rc es
Job control N Y Y Y Y Y N N
Aliases N Y Y Y Y Y N N
Shell functions Y(1) N Y Y N Y Y Y
"Sensible" Input/Output redirection Y N Y Y N Y Y Y
Directory stack N Y Y Y Y Y F F
Command history N Y Y Y Y Y L L
Command line editing N N Y Y Y Y L L
Vi Command line editing N N Y Y Y(3) Y L L
Emacs Command line editing N N Y Y Y Y L L
Rebindable Command line editing N N N Y Y Y L L
User name look up N Y Y Y Y Y L L
Login/Logout watching N N N N Y Y F F
Filename completion N Y(1) Y Y Y Y L L
Username completion N Y(2) Y Y Y Y L L
Hostname completion N Y(2) Y Y Y Y L L
History completion N N N Y Y Y L L
Fully programmable Completion N N N N Y Y N N
Mh Mailbox completion N N N N(4) N(6) N(6) N N
Co Processes N N Y N N Y N N
Builtin artithmetic evaluation N Y Y Y Y Y N N
Can follow symbolic links invisibly N N Y Y Y Y N N
Periodic command execution N N N N Y Y N N
Custom Prompt (easily) N N Y Y Y Y Y Y
Sun Keyboard Hack N N N N N Y N N
Spelling Correction N N N N Y Y N N
Process Substitution N N N Y(2) N Y Y Y
Underlying Syntax sh csh sh sh csh sh rc rc
Freely Available N N N(5) Y Y Y Y Y
Checks Mailbox N Y Y Y Y Y F F
Tty Sanity Checking N N N N Y Y N N
Can cope with large argument lists Y N Y Y Y Y Y Y
Has non-interactive startup file N Y Y(7) Y(7) Y Y N N
Has non-login startup file N Y Y(7) Y Y Y N N
Can avoid user startup files N Y N Y N Y Y Y
Can specify startup file N N Y Y N N N N
Low level command redefinition N N N N N N N Y
Has anonymous functions N N N N N N Y Y
List Variables N Y Y N Y Y Y Y
Full signal trap handling Y N Y Y N Y Y Y
File no clobber ability N Y Y Y Y Y N F
Local variables N N Y Y N Y Y Y
Lexically scoped variables N N N N N N N Y
Exceptions N N N N N N N Y

Key to the table above.

Y Feature can be done using this shell.

N Feature is not present in the shell.

F Feature can only be done by using the shells function
mechanism.

L The readline library must be linked into the shell to enable
this Feature.

Notes to the table above

1. This feature was not in the orginal version, but has since become
almost standard.
2. This feature is fairly new and so is often not found on many
versions of the shell, it is gradually making its way into
standard distribution.
3. The Vi emulation of this shell is thought by many to be
incomplete.
4. This feature is not standard but unoffical patches exist to
perform this.
5. A version called 'pdksh' is freely available, but does not have
the full functionality of the AT&T version.
6. This can be done via the shells programmable completion mechanism.
7. Only by specifing a file via the ENV environment variable.

How to change your shell

If you ever look at a UNIX manual page it will say that to change your
shell use chsh or passwd -s; unfortunately it often isn't as simple as
this, since it requires that your new shell is recognized as a valid
shell by the system and at present many systems do not recognize the
newer shells (the normal selection is, /bin/sh, /bin/csh and possibly
/bin/ksh). You are thus left with having to do some sort of fudge,
changing your effective login shell without changing your official
entry in /etc/passwd. You may also be left with the problem that there
isn't a compiled binary on your system , so you will have to get hold
of the shell's source and compile it yourself (Its generally best to
ask around to see if anyones done this already, since it isn't that
easy). Once done you should add in code to your old shells login file
so that it overlays your official login shell with your new shell
(remember to add the login flags to the command line, and with
csh/tcsh ensure that the overlay doesn't happen recursively since they
both read the same .login file).

The shell can be recognized as a valid shell if the system
administrator puts it in the file /etc/shells. If this file does not
exist, it must be created and should contain all valid shells
(i.e.don't forget the traditional ones in all their forms).

WARNING

If you do decide to change your shell you must be very careful - if
handled wrongly it can be almost impossible to correct, and will
almost certainly cause you a lot of hassle. Never make a new shell a
login shell until you have tested its new configuration files
thoroughly and then tested them once again. It is also important that
you make a full backup of your previous config files onto a floppy
disk (or a different host if you have a second account) if you have to
change any of them (which you will probably have to do if you can't
change your shell entry in /etc/passwd). You should also note that
your new shell is probably not supported by your system admin, so if
you have any problems you will probably have to look elsewhere.

Further information

The Bourne shell, the C-Shell and the Korn Shell (if you have it) are
all distributed as standard with your UNIX operating system,
information on these should come with your operating system, bug
reports etc should be sent to your operating system vendor. The free
version of ksh, pdksh is available as ftp://ftp.cs.mun.ca/pub/pdksh/

A commercial "compiler" (CCsh) is available for the Bourne shell, this
can provide extra speed on some applications. For more information
contact Comeau Computing 91-34 120th Street, Richmond Hill, NY, USA
11418-3214. Email comeau@csanta.attmail.com.

Bash was written and is maintained by the Free Software Foundation,
the primary source of information for this shell is its manual page.
Bug reports should be sent to bash-maintainers@ai.MIT.Edu, while
suggestions and philosophical bug reports may be mailed to
bug-bash@ai.MIT.Edu or posted to the Usenet newsgroup gnu.bash.bug,
the source is widely available on many ftp sites, and is subject to
the GNU copyleft licence.

Tcsh is available by ftp from ftp://ftp.deshaw.com and several other
places.

Rc is available by ftp from ftp://viz.tamu.edu/pub/rc,
ftp://ftp.sys.utotonoto.cs/pub/rc and several other places. An FAQ
exists and is posted frequently to comp.unix.shell and other places.
The Rc mailing list may be subscribed to by sending mail to
rc-request@hawkwind.utcs.toronto.edu, this, the manual page and the Rc
FAQ are the main sources of information for this shell. The original
paper on rc is available as
http://plan9.att.com/plan9/plan9doc/7.ps.Z.

Zsh is available by ftp from ftp://ftp.math.gatech.edu/pub/zsh and at
several mirror sites. Zsh is now maintained by the members of the zsh
mailing lists, which can be subscribed to by sending email to
zsh-announce-request@math.gatech.edu (announcements),
zsh-users-request@math.gatech.edu (users discussions) or
zsh-workers-request@math.gatech.edu (zsh hacking and development) with
a subject of "subscribe email-address", there is also an FAQ which
is posted frequently to comp.unix.shell. The manual page, the Z-shell
FAQ and the zsh-list are the main sources of information for this
shell.

ES is available by ftp from ftp://ftp.cs.utoronto/pub/es and at
several other places, a mailing list can be subscribed to by sending
mail to es-request@hawkwind.utcs.toronto.edu and a paper about es is
at http://www.webcom.com/~haahr/es/es-usenix-winter93.html.

Questions on any of the UNIX shells and on shell script programming,
may be posted to the Usenet newsgroup comp.unix.shell a quick response
can normally be expected, especially on subjects relating to the more
common shells.

BASH Frequently-Asked Questions

This is the Bash FAQ, version 3.26, for Bash version 2.05b.

This document contains a set of frequently-asked questions concerning
Bash, the GNU Bourne-Again Shell. Bash is a freely-available command
interpreter with advanced features for both interactive use and shell
programming.

Another good source of basic information about shells is the collection
of FAQ articles periodically posted to comp.unix.shell.

Questions and comments concerning this document should be sent to
chet@po.cwru.edu.

This document is available for anonymous FTP with the URL

ftp://ftp.cwru.edu/pub/bash/FAQ

The Bash home page is http://cnswww.cns.cwru.edu/~chet/bash/bashtop.html

----------
Contents:

Section A: The Basics

A1) What is it?
A2) What's the latest version?
A3) Where can I get it?
A4) On what machines will bash run?
A5) Will bash run on operating systems other than Unix?
A6) How can I build bash with gcc?
A7) How can I make bash my login shell?
A8) I just changed my login shell to bash, and now I can't FTP into my
machine. Why not?
A9) What's the `POSIX Shell and Utilities standard'?
A10) What is the bash `posix mode'?

Section B: The latest version

B1) What's new in version 2.05b?
B2) Are there any user-visible incompatibilities between bash-2.05b and
bash-1.14.7?

Section C: Differences from other Unix shells

C1) How does bash differ from sh, the Bourne shell?
C2) How does bash differ from the Korn shell, version ksh88?
C3) Which new features in ksh-93 are not in bash, and which are?

Section D: Why does bash do some things differently than other Unix shells?

D1) Why does bash run a different version of `command' than
`which command' says it will?
D2) Why doesn't bash treat brace expansions exactly like csh?
D3) Why doesn't bash have csh variable modifiers?
D4) How can I make my csh aliases work when I convert to bash?
D5) How can I pipe standard output and standard error from one command to
another, like csh does with `|&'?
D6) Now that I've converted from ksh to bash, are there equivalents to
ksh features like autoloaded functions and the `whence' command?

Section E: Why does bash do certain things the way it does?

E1) Why is the bash builtin `test' slightly different from /bin/test?
E2) Why does bash sometimes say `Broken pipe'?
E3) When I have terminal escape sequences in my prompt, why does bash
wrap lines at the wrong column?
E4) If I pipe the output of a command into `read variable', why doesn't
the output show up in $variable when the read command finishes?
E5) I have a bunch of shell scripts that use backslash-escaped characters
in arguments to `echo'. Bash doesn't interpret these characters. Why
not, and how can I make it understand them?
E6) Why doesn't a while or for loop get suspended when I type ^Z?
E7) What about empty for loops in Makefiles?
E8) Why does the arithmetic evaluation code complain about `08'?
E9) Why does the pattern matching expression [A-Z]* match files beginning
with every letter except `z'?
E10) Why does `cd //' leave $PWD as `//'?
E11) If I resize my xterm while another program is running, why doesn't bash
notice the change?
E12) Why don't negative offsets in substring expansion work like I expect?

Section F: Things to watch out for on certain Unix versions

F1) Why can't I use command line editing in my `cmdtool'?
F2) I built bash on Solaris 2. Why do globbing expansions and filename
completion chop off the first few characters of each filename?
F3) Why does bash dump core after I interrupt username completion or
`~user' tilde expansion on a machine running NIS?
F4) I'm running SVR4.2. Why is the line erased every time I type `@'?
F5) Why does bash report syntax errors when my C News scripts use a
redirection before a subshell command?
F6) Why can't I use vi-mode editing on Red Hat Linux 6.1?
F7) Why do bash-2.05a and bash-2.05b fail to compile `printf.def' on
HP/UX 11.x?

Section G: How can I get bash to do certain common things?

G1) How can I get bash to read and display eight-bit characters?
G2) How do I write a function `x' to replace builtin command `x', but
still invoke the command from within the function?
G3) How can I find the value of a shell variable whose name is the value
of another shell variable?
G4) How can I make the bash `time' reserved word print timing output that
looks like the output from my system's /usr/bin/time?
G5) How do I get the current directory into my prompt?
G6) How can I rename "*.foo" to "*.bar"?
G7) How can I translate a filename from uppercase to lowercase?
G8) How can I write a filename expansion (globbing) pattern that will match
all files in the current directory except "." and ".."?

Section H: Where do I go from here?

H1) How do I report bugs in bash, and where should I look for fixes and
advice?
H2) What kind of bash documentation is there?
H3) What's coming in future versions?
H4) What's on the bash `wish list'?
H5) When will the next release appear?

----------
Section A: The Basics

A1) What is it?

Bash is a Unix command interpreter (shell). It is an implementation of
the Posix 1003.2 shell standard, and resembles the Korn and System V
shells.

Bash contains a number of enhancements over those shells, both
for interactive use and shell programming. Features geared
toward interactive use include command line editing, command
history, job control, aliases, and prompt expansion. Programming
features include additional variable expansions, shell
arithmetic, and a number of variables and options to control
shell behavior.

Bash was originally written by Brian Fox of the Free Software
Foundation. The current developer and maintainer is Chet Ramey
of Case Western Reserve University.

A2) What's the latest version?

The latest version is 2.05b, first made available on Wednesday, 17
July, 2002.

A3) Where can I get it?

Bash is the GNU project's shell, and so is available from the
master GNU archive site, ftp.gnu.org, and its mirrors. The
latest version is also available for FTP from ftp.cwru.edu.
The following URLs tell how to get version 2.05b:

ftp://ftp.gnu.org/pub/gnu/bash/bash-2.05b.tar.gz
ftp://ftp.cwru.edu/pub/bash/bash-2.05b.tar.gz

Formatted versions of the documentation are available with the URLs:

ftp://ftp.gnu.org/pub/gnu/bash/bash-doc-2.05b.tar.gz
ftp://ftp.cwru.edu/pub/bash/bash-doc-2.05b.tar.gz

A4) On what machines will bash run?

Bash has been ported to nearly every version of UNIX. All you
should have to do to build it on a machine for which a port
exists is to type `configure' and then `make'. The build process
will attempt to discover the version of UNIX you have and tailor
itself accordingly, using a script created by GNU autoconf.

More information appears in the file `INSTALL' in the distribution.

The Bash web page (http://cnswww.cns.cwru.edu/~chet/bash/bashtop.html)
explains how to obtain binary versions of bash for most of the major
commercial Unix systems.

A5) Will bash run on operating systems other than Unix?

Configuration specifics for Unix-like systems such as QNX and
LynxOS are included in the distribution. Bash-2.05 and later
versions should compile and run on Minix 2.0 (patches were
contributed), but I don't believe anyone has built bash-2.x on
earlier Minix versions yet.

Bash has been ported to versions of Windows implementing the Win32
programming interface. This includes Windows 95 and Windows NT.
The port was done by Cygnus Solutions as part of their CYGWIN
project. For more information about the project, look at the URLs

http://www.cygwin.com/
http://sourceware.cygnus.com/cygwin

Cygnus originally ported bash-1.14.7, and that port was part of their
early GNU-Win32 (the original name) releases. Cygnus has also done a
port of bash-2.05 to the CYGWIN environment, and it is available as
part of their current release.

Bash-2.05b should require no local Cygnus changes to build and run under
CYGWIN.

The Cygnus port works only on Intel machines. There is a port of bash
(I don't know which version) to the alpha/NT environment available from

ftp://ftp.gnustep.org//pub/win32/

DJ Delorie has a port of bash-2.x which runs under MS-DOS, as part
of the DJGPP project. For more information on the project, see

http://www.delorie.com/djgpp/

I have been told that the original DJGPP port was done by Daisuke Aoyama.

Mark Elbrecht has sent me notice that bash-2.04
is available for DJGPP V2. The files are available as:

ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/ binary
ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/ documentation
ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/ source

Mark has begun to work with bash-2.05, but I don't know the status.

Ports of bash-1.12 and bash-2.0 are available for OS/2 from

ftp://hobbes.nmsu.edu/pub/os2/util/shell/bash_112.zip
ftp://hobbes.nmsu.edu/pub/os2/util/shell/bash-2.0(253).zip

I haven't looked at either, but the second appears to be a binary-only
distribution. Beware.

I have received word that Bash (I'm not sure which version, but I
believe that it's at least bash-2.02.1) is the standard shell on
BeOS.

A6) How can I build bash with gcc?

Bash configures to use gcc by default if it is available. Read the
file INSTALL in the distribution for more information.

A7) How can I make bash my login shell?

Some machines let you use `chsh' to change your login shell. Other
systems use `passwd -s' or `passwd -e'. If one of these works for
you, that's all you need. Note that many systems require the full
pathname to a shell to appear in /etc/shells before you can make it
your login shell. For this, you may need the assistance of your
friendly local system administrator.

If you cannot do this, you can still use bash as your login shell, but
you need to perform some tricks. The basic idea is to add a command
to your login shell's startup file to replace your login shell with
bash.

For example, if your login shell is csh or tcsh, and you have installed
bash in /usr/gnu/bin/bash, add the following line to ~/.login:

if ( -f /usr/gnu/bin/bash ) exec /usr/gnu/bin/bash --login

(the `--login' tells bash that it is a login shell).

It's not a good idea to put this command into ~/.cshrc, because every
csh you run without the `-f' option, even ones started to run csh scripts,
reads that file. If you must put the command in ~/.cshrc, use something
like

if ( $?prompt ) exec /usr/gnu/bin/bash --login

to ensure that bash is exec'd only when the csh is interactive.

If your login shell is sh or ksh, you have to do two things.

First, create an empty file in your home directory named `.bash_profile'.
The existence of this file will prevent the exec'd bash from trying to
read ~/.profile, and re-execing itself over and over again. ~/.bash_profile
is the first file bash tries to read initialization commands from when
it is invoked as a login shell.

Next, add a line similar to the above to ~/.profile:

[ -f /usr/gnu/bin/bash ] && [ -x /usr/gnu/bin/bash ] && \
exec /usr/gnu/bin/bash --login

This will cause login shells to replace themselves with bash running as
a login shell. Once you have this working, you can copy your initialization
code from ~/.profile to ~/.bash_profile.

I have received word that the recipe supplied above is insufficient for
machines running CDE. CDE has a maze of twisty little startup files, all
slightly different.

If you cannot change your login shell in the password file to bash, you
will have to (apparently) live with CDE using the shell in the password
file to run its startup scripts. If you have changed your shell to bash,
there is code in the CDE startup files (on Solaris, at least) that attempts
to do the right thing. It is, however, often broken, and may require that
you use the $BASH_ENV trick described below.

`dtterm' claims to use $SHELL as the default program to start, so if you
can change $SHELL in the CDE startup files, you should be able to use bash
in your terminal windows.

Setting DTSOURCEPROFILE in ~/.dtprofile will cause the `Xsession' program
to read your login shell's startup files. You may be able to use bash for
the rest of the CDE programs by setting SHELL to bash in ~/.dtprofile as
well, but I have not tried this.

You can use the above `exec' recipe to start bash when not logging in with
CDE by testing the value of the DT variable:

if [ -n "$DT" ]; then
[ -f /usr/gnu/bin/bash ] && exec /usr/gnu/bin/bash --login
fi

If CDE starts its shells non-interactively during login, the login shell
startup files (~/.profile, ~/.bash_profile) will not be sourced at login.
To get around this problem, append a line similar to the following to your
~/.dtprofile:

BASH_ENV=${HOME}/.bash_profile ; export BASH_ENV

and add the following line to the beginning of ~/.bash_profile:

unset BASH_ENV

A8) I just changed my login shell to bash, and now I can't FTP into my
machine. Why not?

You must add the full pathname to bash to the file /etc/shells. As
noted in the answer to the previous question, many systems require
this before you can make bash your login shell.

Most versions of ftpd use this file to prohibit `special' users
such as `uucp' and `news' from using FTP.

A9) What's the `POSIX Shell and Utilities standard'?

POSIX is a name originally coined by Richard Stallman for a
family of open system standards based on UNIX. There are a
number of aspects of UNIX under consideration for
standardization, from the basic system services at the system
call and C library level to applications and tools to system
administration and management. Each area of standardization is
assigned to a working group in the 1003 series.

The POSIX Shell and Utilities standard was originally developed by
IEEE Working Group 1003.2 (POSIX.2). Today it has been merged with
the original 1003.1 Working Group and is maintained by the Austin
Group (a joint working group of the IEEE, The Open Group and
ISO/IEC SC22/WG15). Today the Shell and Utilities are a volume
within the set of documents that make up IEEE Std 1003.1-2001, and
thus now the former POSIX.2 (from 1992) is now part of the current
POSIX.1 standard (POSIX 1003.1-2001).

The Shell and Utilities volume concentrates on the command
interpreter interface and utility programs commonly executed from
the command line or by other programs. The standard is freely
available on the web at http://www.UNIX-systems.org/version3/ .
Work continues at the Austin Group on maintenance issues; see
http://www.opengroup.org/austin/ to join the discussions.

Bash is concerned with the aspects of the shell's behavior defined
by the POSIX Shell and Utilities volume. The shell command
language has of course been standardized, including the basic flow
control and program execution constructs, I/O redirection and
pipelining, argument handling, variable expansion, and quoting.

The `special' builtins, which must be implemented as part of the
shell to provide the desired functionality, are specified as
being part of the shell; examples of these are `eval' and
`export'. Other utilities appear in the sections of POSIX not
devoted to the shell which are commonly (and in some cases must
be) implemented as builtin commands, such as `read' and `test'.
POSIX also specifies aspects of the shell's interactive
behavior as part of the UPE, including job control and command
line editing. Only vi-style line editing commands have been
standardized; emacs editing commands were left out due to
objections.

The latest version of the POSIX Shell and Utilities standard is
available (now updated to the 2003 Edition incorporating the
Technical Corrigendum 1), as part of the Single UNIX Specification
Version 3 at

http://www.UNIX-systems.org/version3/

A10) What is the bash `posix mode'?

Although bash is an implementation of the POSIX shell
specification, there are areas where the bash default behavior
differs from that spec. The bash `posix mode' changes the bash
behavior in these areas so that it obeys the spec more closely.

Posix mode is entered by starting bash with the --posix or
'-o posix' option or executing `set -o posix' after bash is running.

The specific aspects of bash which change when posix mode is
active are listed in the file POSIX in the bash distribution.
They are also listed in a section in the Bash Reference Manual
(from which that file is generated).

Section B: The latest version

B1) What's new in version 2.05b?

The raison d'etre for bash-2.05b is to make a second intermediate
release containing the first of the new features to be available
in bash-3.0 and get feedback on those features before proceeding.
The major new feature is multibyte character support in both Bash
and Readline.

Bash-2.05b contains the following new features (see the manual page for
complete descriptions and the CHANGES and NEWS files in the bash-2.05b
distribution):

o support for multibyte characters has been added to both bash and readline

o the DEBUG trap is now run *before* simple commands, ((...)) commands,
[[...]] conditional commands, and for ((...)) loops

o the shell now performs arithmetic in the largest integer size the machine
supports (intmax_t)

o there is a new \D{...} prompt expansion; passes the `...' to strftime(3)
and inserts the result into the expanded prompt

o there is a new `here-string' redirection operator: <<< word

o when displaying variables, function attributes and definitions are shown
separately, allowing them to be re-used as input (attempting to re-use
the old output would result in syntax errors).

o `read' has a new `-u fd' option to read from a specified file descriptor

o the bash debugger in examples/bashdb has been modified to work with the
new DEBUG trap semantics, the command set has been made more gdb-like,
and the changes to $LINENO make debugging functions work better

o the expansion of $LINENO inside a shell function is only relative to the
function start if the shell is interactive -- if the shell is running a
script, $LINENO expands to the line number in the script. This is as
POSIX-2001 requires


A short feature history dating from Bash-2.0:

Bash-2.05a introduced the following new features:

o The `printf' builtin has undergone major work

o There is a new read-only `shopt' option: login_shell, which is set by
login shells and unset otherwise

o New `\A' prompt string escape sequence; expanding to time in 24-hour
HH:MM format

o New `-A group/-g' option to complete and compgen; goes group name
completion

o New [+-]O invocation option to set and unset `shopt' options at startup

o ksh-like `ERR' trap

o `for' loops now allow empty word lists after the `in' reserved word

o new `hard' and `soft' arguments for the `ulimit' builtin

o Readline can be configured to place the user at the same point on the line
when retrieving commands from the history list

o Readline can be configured to skip `hidden' files (filenames with a leading
`.' on Unix) when performing completion

Bash-2.05 introduced the following new features:

o This version has once again reverted to using locales and strcoll(3) when
processing pattern matching bracket expressions, as POSIX requires.
o Added a new `--init-file' invocation argument as a synonym for `--rcfile',
per the new GNU coding standards.
o The /dev/tcp and /dev/udp redirections now accept service names as well as
port numbers.
o `complete' and `compgen' now take a `-o value' option, which controls some
of the aspects of that compspec. Valid values are:

default - perform bash default completion if programmable
completion produces no matches
dirnames - perform directory name completion if programmable
completion produces no matches
filenames - tell readline that the compspec produces filenames,
so it can do things like append slashes to
directory names and suppress trailing spaces
o A new loadable builtin, realpath, which canonicalizes and expands symlinks
in pathname arguments.
o When `set' is called without options, it prints function defintions in a
way that allows them to be reused as input. This affects `declare' and
`declare -p' as well. This only happens when the shell is not in POSIX
mode, since POSIX.2 forbids this behavior.

Bash-2.04 introduced the following new features:

o Programmable word completion with the new `complete' and `compgen' builtins;
examples are provided in examples/complete/complete-examples
o `history' has a new `-d' option to delete a history entry
o `bind' has a new `-x' option to bind key sequences to shell commands
o The prompt expansion code has new `\j' and `\l' escape sequences
o The `no_empty_cmd_completion' shell option, if enabled, inhibits
command completion when TAB is typed on an empty line
o `help' has a new `-s' option to print a usage synopsis
o New arithmetic operators: var++, var--, ++var, --var, expr1,expr2 (comma)
o New ksh93-style arithmetic for command:
for ((expr1 ; expr2; expr3 )); do list; done
o `read' has new options: `-t', `-n', `-d', `-s'
o The redirection code handles several filenames specially: /dev/fd/N,
/dev/stdin, /dev/stdout, /dev/stderr
o The redirection code now recognizes /dev/tcp/HOST/PORT and
/dev/udp/HOST/PORT and tries to open a TCP or UDP socket, respectively,
to the specified port on the specified host
o The ${!prefix*} expansion has been implemented
o A new FUNCNAME variable, which expands to the name of a currently-executing
function
o The GROUPS variable is no longer readonly
o A new shopt `xpg_echo' variable, to control the behavior of echo with
respect to backslash-escape sequences at runtime
o The NON_INTERACTIVE_LOGIN_SHELLS #define has returned

The version of Readline released with Bash-2.04, Readline-4.1, had several
new features as well:

o Parentheses matching is always compiled into readline, and controllable
with the new `blink-matching-paren' variable
o The history-search-forward and history-search-backward functions now leave
point at the end of the line when the search string is empty, like
reverse-search-history, and forward-search-history
o A new function for applications: rl_on_new_line_with_prompt()
o New variables for applications: rl_already_prompted, and rl_gnu_readline_p


Bash-2.03 had very few new features, in keeping with the convention
that odd-numbered releases provide mainly bug fixes. A number of new
features were added to Readline, mostly at the request of the Cygnus
folks.

A new shopt option, `restricted_shell', so that startup files can test
whether or not the shell was started in restricted mode
Filename generation is now performed on the words between ( and ) in
compound array assignments (this is really a bug fix)
OLDPWD is now auto-exported, as POSIX.2 requires
ENV and BASH_ENV are read-only variables in a restricted shell
Bash may now be linked against an already-installed Readline library,
as long as the Readline library is version 4 or newer
All shells begun with the `--login' option will source the login shell
startup files, even if the shell is not interactive

There were lots of changes to the version of the Readline library released
along with Bash-2.03. For a complete list of the changes, read the file
CHANGES in the Bash-2.03 distribution.

Bash-2.02 contained the following new features:

a new version of malloc (based on the old GNU malloc code in previous
bash versions) that is more page-oriented, more conservative
with memory usage, does not `orphan' large blocks when they
are freed, is usable on 64-bit machines, and has allocation
checking turned on unconditionally
POSIX.2-style globbing character classes ([:alpha:], [:alnum:], etc.)
POSIX.2-style globbing equivalence classes
POSIX.2-style globbing collating symbols
the ksh [[...]] extended conditional command
the ksh egrep-style extended pattern matching operators
a new `printf' builtin
the ksh-like $( $(cat filename)
new tilde prefixes that expand to directories from the directory stack
new `**' arithmetic operator to do exponentiation
case-insensitive globbing (filename expansion)
menu completion a la tcsh
`magic-space' history expansion function like tcsh
the readline inputrc `language' has a new file inclusion directive ($include)

Bash-2.01 contained only a few new features:

new `GROUPS' builtin array variable containing the user's group list
new bindable readline commands: history-and-alias-expand-line and
alias-expand-line

Bash-2.0 contained extensive changes and new features from bash-1.14.7.
Here's a short list:

new `time' reserved word to time pipelines, shell builtins, and
shell functions
one-dimensional arrays with a new compound assignment statement,
appropriate expansion constructs and modifications to some
of the builtins (read, declare, etc.) to use them
new quoting syntaxes for ANSI-C string expansion and locale-specific
string translation
new expansions to do substring extraction, pattern replacement, and
indirect variable expansion
new builtins: `disown' and `shopt'
new variables: HISTIGNORE, SHELLOPTS, PIPESTATUS, DIRSTACK, GLOBIGNORE,
MACHTYPE, BASH_VERSINFO
special handling of many unused or redundant variables removed
(e.g., $notify, $glob_dot_filenames, $no_exit_on_failed_exec)
dynamic loading of new builtin commands; many loadable examples provided
new prompt expansions: \a, \e, \n, \H, \T, \@, \v, \V
history and aliases available in shell scripts
new readline variables: enable-keypad, mark-directories, input-meta,
visible-stats, disable-completion, comment-begin
new readline commands to manipulate the mark and operate on the region
new readline emacs mode commands and bindings for ksh-88 compatibility
updated and extended builtins
new DEBUG trap
expanded (and now documented) restricted shell mode

implementation stuff:
autoconf-based configuration
nearly all of the bugs reported since version 1.14 have been fixed
most builtins converted to use builtin `getopt' for consistency
most builtins use -p option to display output in a reusable form
(for consistency)
grammar tighter and smaller (66 reduce-reduce conflicts gone)
lots of code now smaller and faster
test suite greatly expanded

B2) Are there any user-visible incompatibilities between bash-2.05b and
bash-1.14.7?

There are a few incompatibilities between version 1.14.7 and version 2.05b.
They are detailed in the file COMPAT in the bash distribution. That file
is not meant to be all-encompassing; send mail to bash-maintainers@gnu.org
if if you find something that's not mentioned there.

Section C: Differences from other Unix shells

C1) How does bash differ from sh, the Bourne shell?

This is a non-comprehensive list of features that differentiate bash
from the SVR4.2 shell. The bash manual page explains these more
completely.

Things bash has that sh does not:
long invocation options
[+-]O invocation option
-l invocation option
`!' reserved word to invert pipeline return value
`time' reserved word to time pipelines and shell builtins
the `function' reserved word
the `select' compound command and reserved word
arithmetic for command: for ((expr1 ; expr2; expr3 )); do list; done
new $'...' and $"..." quoting
the $(...) form of command substitution
the $( $(cat filename)
the ${#param} parameter value length operator
the ${!param} indirect parameter expansion operator
the ${!param*} prefix expansion operator
the ${param:offset[:length]} parameter substring operator
the ${param/pat[/string]} parameter pattern substitution operator
expansions to perform substring removal (${p%[%]w}, ${p#[#]w})
expansion of positional parameters beyond $9 with ${num}
variables: BASH, BASH_VERSION, BASH_VERSINFO, UID, EUID, REPLY,
TIMEFORMAT, PPID, PWD, OLDPWD, SHLVL, RANDOM, SECONDS,
LINENO, HISTCMD, HOSTTYPE, OSTYPE, MACHTYPE, HOSTNAME,
ENV, PS3, PS4, DIRSTACK, PIPESTATUS, HISTSIZE, HISTFILE,
HISTFILESIZE, HISTCONTROL, HISTIGNORE, GLOBIGNORE, GROUPS,
PROMPT_COMMAND, FCEDIT, FIGNORE, IGNOREEOF, INPUTRC,
SHELLOPTS, OPTERR, HOSTFILE, TMOUT, FUNCNAME, histchars,
auto_resume
DEBUG trap
ERR trap
variable arrays with new compound assignment syntax
redirections: <>, &>, >|, <<<, [n]<&word-, [n]>&word-
prompt string special char translation and variable expansion
auto-export of variables in initial environment
command search finds functions before builtins
bash return builtin will exit a file sourced with `.'
builtins: cd -/-L/-P, exec -l/-c/-a, echo -e/-E, hash -d/-l/-p/-t.
export -n/-f/-p/name=value, pwd -L/-P,
read -e/-p/-a/-t/-n/-d/-s/-u,
readonly -a/-f/name=value, trap -l, set +o,
set -b/-m/-o option/-h/-p/-B/-C/-H/-P,
unset -f/-v, ulimit -m/-p/-u,
type -a/-p/-t/-f/-P, suspend -f, kill -n,
test -o optname/s1 == s2/s1 < s2/s1 > s2/-nt/-ot/-ef/-O/-G/-S
bash reads ~/.bashrc for interactive shells, $ENV for non-interactive
bash restricted shell mode is more extensive
bash allows functions and variables with the same name
brace expansion
tilde expansion
arithmetic expansion with $((...)) and `let' builtin
the `[[...]]' extended conditional command
process substitution
aliases and alias/unalias builtins
local variables in functions and `local' builtin
readline and command-line editing with programmable completion
command history and history/fc builtins
csh-like history expansion
other new bash builtins: bind, command, compgen, complete, builtin,
declare/typeset, dirs, enable, fc, help,
history, logout, popd, pushd, disown, shopt,
printf
exported functions
filename generation when using output redirection (command >a*)
POSIX.2-style globbing character classes
POSIX.2-style globbing equivalence classes
POSIX.2-style globbing collating symbols
egrep-like extended pattern matching operators
case-insensitive pattern matching and globbing
variable assignments preceding commands affect only that command,
even for builtins and functions
posix mode
redirection to /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr,
/dev/tcp/host/port, /dev/udp/host/port

Things sh has that bash does not:
uses variable SHACCT to do shell accounting
includes `stop' builtin (bash can use alias stop='kill -s STOP')
`newgrp' builtin
turns on job control if called as `jsh'
$TIMEOUT (like bash $TMOUT)
`^' is a synonym for `|'
new SVR4.2 sh builtins: mldmode, priv

Implementation differences:
redirection to/from compound commands causes sh to create a subshell
bash does not allow unbalanced quotes; sh silently inserts them at EOF
bash does not mess with signal 11
sh sets (euid, egid) to (uid, gid) if -p not supplied and uid < 100
bash splits only the results of expansions on IFS, using POSIX.2
field splitting rules; sh splits all words on IFS
sh does not allow MAILCHECK to be unset (?)
sh does not allow traps on SIGALRM or SIGCHLD
bash allows multiple option arguments when invoked (e.g. -x -v);
sh allows only a single option argument (`sh -x -v' attempts
to open a file named `-v', and, on SunOS 4.1.4, dumps core.
On Solaris 2.4 and earlier versions, sh goes into an infinite
loop.)
sh exits a script if any builtin fails; bash exits only if one of
the POSIX.2 `special' builtins fails

C2) How does bash differ from the Korn shell, version ksh88?

Things bash has or uses that ksh88 does not:
long invocation options
[-+]O invocation option
-l invocation option
`!' reserved word
arithmetic for command: for ((expr1 ; expr2; expr3 )); do list; done
arithmetic in largest machine-supported size (intmax_t)
posix mode and posix conformance
command hashing
tilde expansion for assignment statements that look like $PATH
process substitution with named pipes if /dev/fd is not available
the ${!param} indirect parameter expansion operator
the ${!param*} prefix expansion operator
the ${param:offset[:length]} parameter substring operator
the ${param/pat[/string]} parameter pattern substitution operator
variables: BASH, BASH_VERSION, BASH_VERSINFO, UID, EUID, SHLVL,
TIMEFORMAT, HISTCMD, HOSTTYPE, OSTYPE, MACHTYPE,
HISTFILESIZE, HISTIGNORE, HISTCONTROL, PROMPT_COMMAND,
IGNOREEOF, FIGNORE, INPUTRC, HOSTFILE, DIRSTACK,
PIPESTATUS, HOSTNAME, OPTERR, SHELLOPTS, GLOBIGNORE,
GROUPS, FUNCNAME, histchars, auto_resume
prompt expansion with backslash escapes and command substitution
redirection: &> (stdout and stderr), <<<, [n]<&word-, [n]>&word-
more extensive and extensible editing and programmable completion
builtins: bind, builtin, command, declare, dirs, echo -e/-E, enable,
exec -l/-c/-a, fc -s, export -n/-f/-p, hash, help, history,
jobs -x/-r/-s, kill -s/-n/-l, local, logout, popd, pushd,
read -e/-p/-a/-t/-n/-d/-s, readonly -a/-n/-f/-p,
set -o braceexpand/-o histexpand/-o interactive-comments/
-o notify/-o physical/-o posix/-o hashall/-o onecmd/
-h/-B/-C/-b/-H/-P, set +o, suspend, trap -l, type,
typeset -a/-F/-p, ulimit -u, umask -S, alias -p, shopt,
disown, printf, complete, compgen
`!' csh-style history expansion
POSIX.2-style globbing character classes
POSIX.2-style globbing equivalence classes
POSIX.2-style globbing collating symbols
egrep-like extended pattern matching operators
case-insensitive pattern matching and globbing
`**' arithmetic operator to do exponentiation
redirection to /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr
arrays of unlimited size
TMOUT is default timeout for `read' and `select'

Things ksh88 has or uses that bash does not:
tracked aliases (alias -t)
variables: ERRNO, FPATH, EDITOR, VISUAL
co-processes (|&, >&p, <&p)
weirdly-scoped functions
typeset +f to list all function names without definitions
text of command history kept in a file, not memory
builtins: alias -x, cd old new, fc -e -, newgrp, print,
read -p/-s/var?prompt, set -A/-o gmacs/
-o bgnice/-o markdirs/-o nolog/-o trackall/-o viraw/-s,
typeset -H/-L/-R/-Z/-A/-ft/-fu/-fx/-l/-u/-t, whence
using environment to pass attributes of exported variables
arithmetic evaluation done on arguments to some builtins
reads .profile from $PWD when invoked as login shell

Implementation differences:
ksh runs last command of a pipeline in parent shell context
bash has brace expansion by default (ksh88 compile-time option)
bash has fixed startup file for all interactive shells; ksh reads $ENV
bash has exported functions
bash command search finds functions before builtins
bash waits for all commands in pipeline to exit before returning status
emacs-mode editing has some slightly different key bindings

C3) Which new features in ksh-93 are not in bash, and which are?

New things in ksh-93 not in bash-2.05b:
associative arrays
floating point arithmetic and variables
math library functions
${!name[sub]} name of subscript for associative array
`.' is allowed in variable names to create a hierarchical namespace
more extensive compound assignment syntax
discipline functions
`sleep' and `getconf' builtins (bash has loadable versions)
typeset -n and `nameref' variables
KEYBD trap
variables: .sh.edchar, .sh.edmode, .sh.edcol, .sh.edtext, .sh.version,
.sh.name, .sh.subscript, .sh.value, .sh.match, HISTEDIT
backreferences in pattern matching (\N)
`&' operator in pattern lists for matching
print -f (bash uses printf)
`fc' has been renamed to `hist'
`.' can execute shell functions
exit statuses between 0 and 255
set -o pipefail
`+=' variable assignment operator
FPATH and PATH mixing
getopts -a
-I invocation option
DEBUG trap now executed before each simple command, instead of after
printf %H, %P, %T, %Z modifiers, output base for %d
lexical scoping for local variables in `ksh' functions
no scoping for local variables in `POSIX' functions

New things in ksh-93 present in bash-2.05b:
[n]<&word- and [n]>&word- redirections (combination dup and close)
for (( expr1; expr2; expr3 )) ; do list; done - arithmetic for command
?:, ++, --, `expr1 , expr2' arithmetic operators
expansions: ${!param}, ${param:offset[:len]}, ${param/pat[/str]},
${!param*}
compound array assignment
the `!' reserved word
loadable builtins -- but ksh uses `builtin' while bash uses `enable'
`command', `builtin', `disown' builtins
new $'...' and $"..." quoting
FIGNORE (but bash uses GLOBIGNORE), HISTCMD
set -o notify/-C
changes to kill builtin
read -A (bash uses read -a)
read -t/-d
trap -p
exec -c/-a
`.' restores the positional parameters when it completes
POSIX.2 `test'
umask -S
unalias -a
command and arithmetic substitution performed on PS1, PS4, and ENV
command name completion
ENV processed only for interactive shells

Section D: Why does bash do some things differently than other Unix shells?

D1) Why does bash run a different version of `command' than
`which command' says it will?

On many systems, `which' is actually a csh script that assumes
you're running csh. In tcsh, `which' and its cousin `where'
are builtins. On other Unix systems, `which' is a perl script
that uses the PATH environment variable.

The csh script version reads the csh startup files from your
home directory and uses those to determine which `command' will
be invoked. Since bash doesn't use any of those startup files,
there's a good chance that your bash environment differs from
your csh environment. The bash `type' builtin does everything
`which' does, and will report correct results for the running
shell. If you're really wedded to the name `which', try adding
the following function definition to your .bashrc:

which()
{
builtin type "$@"
}

If you're moving from tcsh and would like to bring `where' along
as well, use this function:

where()
{
builtin type -a "$@"
}

D2) Why doesn't bash treat brace expansions exactly like csh?

The only difference between bash and csh brace expansion is that
bash requires a brace expression to contain at least one unquoted
comma if it is to be expanded. Any brace-surrounded word not
containing an unquoted comma is left unchanged by the brace
expansion code. This affords the greatest degree of sh
compatibility.

Bash, ksh, zsh, and pd-ksh all implement brace expansion this way.

D3) Why doesn't bash have csh variable modifiers?

Posix has specified a more powerful, albeit somewhat more cryptic,
mechanism cribbed from ksh, and bash implements it.

${parameter%word}
Remove smallest suffix pattern. The WORD is expanded to produce
a pattern. It then expands to the value of PARAMETER, with the
smallest portion of the suffix matched by the pattern deleted.

x=file.c
echo ${x%.c}.o
-->file.o

${parameter%%word}

Remove largest suffix pattern. The WORD is expanded to produce
a pattern. It then expands to the value of PARAMETER, with the
largest portion of the suffix matched by the pattern deleted.

x=posix/src/std
echo ${x%%/*}
-->posix

${parameter#word}
Remove smallest prefix pattern. The WORD is expanded to produce
a pattern. It then expands to the value of PARAMETER, with the
smallest portion of the prefix matched by the pattern deleted.

x=$HOME/src/cmd
echo ${x#$HOME}
-->/src/cmd

${parameter##word}
Remove largest prefix pattern. The WORD is expanded to produce
a pattern. It then expands to the value of PARAMETER, with the
largest portion of the prefix matched by the pattern deleted.

x=/one/two/three
echo ${x##*/}
-->three


Given
a=/a/b/c/d
b=b.xxx

csh bash result
--- ---- ------
$a:h ${a%/*} /a/b/c
$a:t ${a##*/} d
$b:r ${b%.*} b
$b:e ${b##*.} xxx


D4) How can I make my csh aliases work when I convert to bash?

Bash uses a different syntax to support aliases than csh does.
The details can be found in the documentation. We have provided
a shell script which does most of the work of conversion for you;
this script can be found in ./examples/misc/aliasconv.sh. Here is
how you use it:

Start csh in the normal way for you. (e.g., `csh')

Pipe the output of `alias' through `aliasconv.sh', saving the
results into `bash_aliases':

alias | bash aliasconv.sh >bash_aliases

Edit `bash_aliases', carefully reading through any created
functions. You will need to change the names of some csh specific
variables to the bash equivalents. The script converts $cwd to
$PWD, $term to $TERM, $home to $HOME, $user to $USER, and $prompt
to $PS1. You may also have to add quotes to avoid unwanted
expansion.

For example, the csh alias:

alias cd 'cd \!*; echo $cwd'

is converted to the bash function:

cd () { command cd "$@"; echo $PWD ; }

The only thing that needs to be done is to quote $PWD:

cd () { command cd "$@"; echo "$PWD" ; }

Merge the edited file into your ~/.bashrc.

There is an additional, more ambitious, script in
examples/misc/cshtobash that attempts to convert your entire csh
environment to its bash equivalent. This script can be run as
simply `cshtobash' to convert your normal interactive
environment, or as `cshtobash ~/.login' to convert your login
environment.

D5) How can I pipe standard output and standard error from one command to
another, like csh does with `|&'?

Use
command 2>&1 | command2

The key is to remember that piping is performed before redirection, so
file descriptor 1 points to the pipe when it is duplicated onto file
descriptor 2.

D6) Now that I've converted from ksh to bash, are there equivalents to
ksh features like autoloaded functions and the `whence' command?

There are features in ksh-88 and ksh-93 that do not have direct bash
equivalents. Most, however, can be emulated with very little trouble.

ksh-88 feature Bash equivalent
-------------- ---------------
compiled-in aliases set up aliases in .bashrc; some ksh aliases are
bash builtins (hash, history, type)
coprocesses named pipe pairs (one for read, one for write)
typeset +f declare -F
cd, print, whence function substitutes in examples/functions/kshenv
autoloaded functions examples/functions/autoload is the same as typeset -fu
read var?prompt read -p prompt var

ksh-93 feature Bash equivalent
-------------- ---------------
sleep, getconf Bash has loadable versions in examples/loadables
${.sh.version} $BASH_VERSION
print -f printf
hist alias hist=fc
$HISTEDIT $FCEDIT

Section E: How can I get bash to do certain things, and why does bash do
things the way it does?

E1) Why is the bash builtin `test' slightly different from /bin/test?

The specific example used here is [ ! x -o x ], which is false.

Bash's builtin `test' implements the Posix.2 spec, which can be
summarized as follows (the wording is due to David Korn):

Here is the set of rules for processing test arguments.

0 Args: False
1 Arg: True iff argument is not null.
2 Args: If first arg is !, True iff second argument is null.
If first argument is unary, then true if unary test is true
Otherwise error.
3 Args: If second argument is a binary operator, do binary test of $1 $3
If first argument is !, negate two argument test of $2 $3
If first argument is `(' and third argument is `)', do the
one-argument test of the second argument.
Otherwise error.
4 Args: If first argument is !, negate three argument test of $2 $3 $4.
Otherwise unspecified
5 or more Args: unspecified. (Historical shells would use their
current algorithm).

The operators -a and -o are considered binary operators for the purpose
of the 3 Arg case.

As you can see, the test becomes (not (x or x)), which is false.

E2) Why does bash sometimes say `Broken pipe'?

If a sequence of commands appears in a pipeline, and one of the
reading commands finishes before the writer has finished, the
writer receives a SIGPIPE signal. Many other shells special-case
SIGPIPE as an exit status in the pipeline and do not report it.
For example, in:

ps -aux | head

`head' can finish before `ps' writes all of its output, and ps
will try to write on a pipe without a reader. In that case, bash
will print `Broken pipe' to stderr when ps is killed by a
SIGPIPE.

You can build a version of bash that will not report SIGPIPE errors
by uncommenting the definition of DONT_REPORT_SIGPIPE in the file
config-top.h.

E3) When I have terminal escape sequences in my prompt, why does bash
wrap lines at the wrong column?

Readline, the line editing library that bash uses, does not know
that the terminal escape sequences do not take up space on the
screen. The redisplay code assumes, unless told otherwise, that
each character in the prompt is a `printable' character that
takes up one character position on the screen.

You can use the bash prompt expansion facility (see the PROMPTING
section in the manual page) to tell readline that sequences of
characters in the prompt strings take up no screen space.

Use the \[ escape to begin a sequence of non-printing characters,
and the \] escape to signal the end of such a sequence.

E4) If I pipe the output of a command into `read variable', why doesn't
the output show up in $variable when the read command finishes?

This has to do with the parent-child relationship between Unix
processes. It affects all commands run in pipelines, not just
simple calls to `read'. For example, piping a command's output
into a `while' loop that repeatedly calls `read' will result in
the same behavior.

Each element of a pipeline runs in a separate process, a child of
the shell running the pipeline. A subprocess cannot affect its
parent's environment. When the `read' command sets the variable
to the input, that variable is set only in the subshell, not the
parent shell. When the subshell exits, the value of the variable
is lost.

Many pipelines that end with `read variable' can be converted
into command substitutions, which will capture the output of
a specified command. The output can then be assigned to a
variable:

grep ^gnu /usr/lib/news/active | wc -l | read ngroup

can be converted into

ngroup=$(grep ^gnu /usr/lib/news/active | wc -l)

This does not, unfortunately, work to split the text among
multiple variables, as read does when given multiple variable
arguments. If you need to do this, you can either use the
command substitution above to read the output into a variable
and chop up the variable using the bash pattern removal
expansion operators or use some variant of the following
approach.

Say /usr/local/bin/ipaddr is the following shell script:

#! /bin/sh
host `hostname` | awk '/address/ {print $NF}'

Instead of using

/usr/local/bin/ipaddr | read A B C D

to break the local machine's IP address into separate octets, use

OIFS="$IFS"
IFS=.
set -- $(/usr/local/bin/ipaddr)
IFS="$OIFS"
A="$1" B="$2" C="$3" D="$4"

Beware, however, that this will change the shell's positional
parameters. If you need them, you should save them before doing
this.

This is the general approach -- in most cases you will not need to
set $IFS to a different value.

Some other user-supplied alternatives include:

read A B C D << HERE
$(IFS=.; echo $(/usr/local/bin/ipaddr))
HERE

and, where process substitution is available,

read A B C D < <(IFS=.; echo $(/usr/local/bin/ipaddr))

E5) I have a bunch of shell scripts that use backslash-escaped characters
in arguments to `echo'. Bash doesn't interpret these characters. Why
not, and how can I make it understand them?

This is the behavior of echo on most Unix System V machines.

The bash builtin `echo' is modeled after the 9th Edition
Research Unix version of `echo'. It does not interpret
backslash-escaped characters in its argument strings by default;
it requires the use of the -e option to enable the
interpretation. The System V echo provides no way to disable the
special characters; the bash echo has a -E option to disable
them.

There is a configuration option that will make bash behave like
the System V echo and interpret things like `\t' by default. Run
configure with the --enable-xpg-echo-default option to turn this
on. Be aware that this will cause some of the tests run when you
type `make tests' to fail.

There is a shell option, `xpg_echo', settable with `shopt', that will
change the behavior of echo at runtime. Enabling this option turns
on expansion of backslash-escape sequences.

E6) Why doesn't a while or for loop get suspended when I type ^Z?

This is a consequence of how job control works on Unix. The only
thing that can be suspended is the process group. This is a single
command or pipeline of commands that the shell forks and executes.

When you run a while or for loop, the only thing that the shell forks
and executes are any commands in the while loop test and commands in
the loop bodies. These, therefore, are the only things that can be
suspended when you type ^Z.

If you want to be able to stop the entire loop, you need to put it
within parentheses, which will force the loop into a subshell that
may be stopped (and subsequently restarted) as a single unit.

E7) What about empty for loops in Makefiles?

It's fairly common to see constructs like this in automatically-generated
Makefiles:

SUBDIRS = @SUBDIRS@

...

subdirs-clean:
for d in ${SUBDIRS}; do \
( cd $$d && ${MAKE} ${MFLAGS} clean ) \
done

When SUBDIRS is empty, this results in a command like this being passed to
bash:

for d in ; do
( cd $d && ${MAKE} ${MFLAGS} clean )
done

In versions of bash before bash-2.05a, this was a syntax error. If the
reserved word `in' was present, a word must follow it before the semicolon
or newline. The language in the manual page referring to the list of words
being empty referred to the list after it is expanded. These versions of
bash required that there be at least one word following the `in' when the
construct was parsed.

The idiomatic Makefile solution is something like:

SUBDIRS = @SUBDIRS@

subdirs-clean:
subdirs=$SUBDIRS ; for d in $$subdirs; do \
( cd $$d && ${MAKE} ${MFLAGS} clean ) \
done

The latest drafts of the updated POSIX standard have changed this: the
word list is no longer required. Bash versions 2.05a and later accept
the new syntax.

E8) Why does the arithmetic evaluation code complain about `08'?

The bash arithmetic evaluation code (used for `let', $(()), (()), and in
other places), interprets a leading `0' in numeric constants as denoting
an octal number, and a leading `0x' as denoting hexadecimal. This is
in accordance with the POSIX.2 spec, section 2.9.2.1, which states that
arithmetic constants should be handled as signed long integers as defined
by the ANSI/ISO C standard.

The POSIX.2 interpretation committee has confirmed this:

http://www.pasc.org/interps/unofficial/db/p1003.2/pasc-1003.2-173.html

E9) Why does the pattern matching expression [A-Z]* match files beginning
with every letter except `z'?

Bash-2.03, Bash-2.05 and later versions honor the current locale setting
when processing ranges within pattern matching bracket expressions ([A-Z]).
This is what POSIX.2 and SUSv3/XPG6 specify.

The behavior of the matcher in bash-2.05 and later versions depends on the
current LC_COLLATE setting. Setting this variable to `C' or `POSIX' will
result in the traditional behavior ([A-Z] matches all uppercase ASCII
characters). Many other locales, including the en_US locale (the default
on many US versions of Linux) collate the upper and lower case letters like
this:

AaBb...Zz

which means that [A-Z] matches every letter except `z'. Others collate like

aAbBcC...zZ

which means that [A-Z] matches every letter except `a'.

The portable way to specify upper case letters is [:upper:] instead of
A-Z; lower case may be specified as [:lower:] instead of a-z.

Look at the manual pages for setlocale(3), strcoll(3), and, if it is
present, locale(1). If you have locale(1), you can use it to find
your current locale information even if you do not have any of the
LC_ variables set.

My advice is to put

export LC_COLLATE=C

into /etc/profile and inspect any shell scripts run from cron for
constructs like [A-Z]. This will prevent things like

rm [A-Z]*

from removing every file in the current directory except those beginning
with `z' and still allow individual users to change the collation order.
Users may put the above command into their own profiles as well, of course.

E10) Why does `cd //' leave $PWD as `//'?

POSIX.2, in its description of `cd', says that *three* or more leading
slashes may be replaced with a single slash when canonicalizing the
current working directory.

This is, I presume, for historical compatibility. Certain versions of
Unix, and early network file systems, used paths of the form
//hostname/path to access `path' on server `hostname'.

E11) If I resize my xterm while another program is running, why doesn't bash
notice the change?

This is another issue that deals with job control.

The kernel maintains a notion of a current terminal process group. Members
of this process group (processes whose process group ID is equal to the
current terminal process group ID) receive terminal-generated signals like
SIGWINCH. (For more details, see the JOB CONTROL section of the bash
man page.)

If a terminal is resized, the kernel sends SIGWINCH to each member of
the terminal's current process group (the `foreground' process group).

When bash is running with job control enabled, each pipeline (which may be
a single command) is run in its own process group, different from bash's
process group. This foreground process group receives the SIGWINCH; bash
does not. Bash has no way of knowing that the terminal has been resized.

There is a `checkwinsize' option, settable with the `shopt' builtin, that
will cause bash to check the window size and adjust its idea of the
terminal's dimensions each time a process stops or exits and returns control
of the terminal to bash. Enable it with `shopt -s checkwinsize'.

E12) Why don't negative offsets in substring expansion work like I expect?

When substring expansion of the form ${param:offset[:length} is used,
an `offset' that evaluates to a number less than zero counts back from
the end of the expanded value of $param.

When a negative `offset' begins with a minus sign, however, unexpected things
can happen. Consider

a=12345678
echo ${a:-4}

intending to print the last four characters of $a. The problem is that
${param:-word} already has a well-defined meaning: expand to word if the
expanded value of param is unset or null, and $param otherwise.

To use negative offsets that begin with a minus sign, separate the
minus sign and the colon with a space.

Section F: Things to watch out for on certain Unix versions

F1) Why can't I use command line editing in my `cmdtool'?

The problem is `cmdtool' and bash fighting over the input. When
scrolling is enabled in a cmdtool window, cmdtool puts the tty in
`raw mode' to permit command-line editing using the mouse for
applications that cannot do it themselves. As a result, bash and
cmdtool each try to read keyboard input immediately, with neither
getting enough of it to be useful.

This mode also causes cmdtool to not implement many of the
terminal functions and control sequences appearing in the
`sun-cmd' termcap entry. For a more complete explanation, see
that file examples/suncmd.termcap in the bash distribution.

`xterm' is a better choice, and gets along with bash much more
smoothly.

If you must use cmdtool, you can use the termcap description in
examples/suncmd.termcap. Set the TERMCAP variable to the terminal
description contained in that file, i.e.

TERMCAP='Mu|sun-cmd:am:bs:km:pt:li#34:co#80:cl=^L:ce=\E[K:cd=\E[J:rs=\E[s:'

Then export TERMCAP and start a new cmdtool window from that shell.
The bash command-line editing should behave better in the new
cmdtool. If this works, you can put the assignment to TERMCAP
in your bashrc file.

F2) I built bash on Solaris 2. Why do globbing expansions and filename
completion chop off the first few characters of each filename?

This is the consequence of building bash on SunOS 5 and linking
with the libraries in /usr/ucblib, but using the definitions
and structures from files in /usr/include.

The actual conflict is between the dirent structure in
/usr/include/dirent.h and the struct returned by the version of
`readdir' in libucb.a (a 4.3-BSD style `struct direct').

Make sure you've got /usr/ccs/bin ahead of /usr/ucb in your $PATH
when configuring and building bash. This will ensure that you
use /usr/ccs/bin/cc or acc instead of /usr/ucb/cc and that you
link with libc before libucb.

If you have installed the Sun C compiler, you may also need to
put /usr/ccs/bin and /opt/SUNWspro/bin into your $PATH before
/usr/ucb.

F3) Why does bash dump core after I interrupt username completion or
`~user' tilde expansion on a machine running NIS?

This is a famous and long-standing bug in the SunOS YP (sorry, NIS)
client library, which is part of libc.

The YP library code keeps static state -- a pointer into the data
returned from the server. When YP initializes itself (setpwent),
it looks at this pointer and calls free on it if it's non-null.
So far, so good.

If one of the YP functions is interrupted during getpwent (the
exact function is interpretwithsave()), and returns NULL, the
pointer is freed without being reset to NULL, and the function
returns. The next time getpwent is called, it sees that this
pointer is non-null, calls free, and the bash free() blows up
because it's being asked to free freed memory.

The traditional Unix mallocs allow memory to be freed multiple
times; that's probably why this has never been fixed. You can
run configure with the `--without-gnu-malloc' option to use
the C library malloc and avoid the problem.

F4) I'm running SVR4.2. Why is the line erased every time I type `@'?

The `@' character is the default `line kill' character in most
versions of System V, including SVR4.2. You can change this
character to whatever you want using `stty'. For example, to
change the line kill character to control-u, type

stty kill ^U

where the `^' and `U' can be two separate characters.

F5) Why does bash report syntax errors when my C News scripts use a
redirection before a subshell command?

The actual command in question is something like

< file ( command )

According to the grammar given in the POSIX.2 standard, this construct
is, in fact, a syntax error. Redirections may only precede `simple
commands'. A subshell construct such as the above is one of the shell's
`compound commands'. A redirection may only follow a compound command.

This affects the mechanical transformation of commands that use `cat'
to pipe a file into a command (a favorite Useless-Use-Of-Cat topic on
comp.unix.shell). While most commands of the form

cat file | command

can be converted to `< file command', shell control structures such as
loops and subshells require `command < file'.

The file CWRU/sh-redir-hack in the bash-2.05a distribution is an
(unofficial) patch to parse.y that will modify the grammar to
support this construct. It will not apply with `patch'; you must
modify parse.y by hand. Note that if you apply this, you must
recompile with -DREDIRECTION_HACK. This introduces a large
number of reduce/reduce conflicts into the shell grammar.

F6) Why can't I use vi-mode editing on Red Hat Linux 6.1?

The short answer is that Red Hat screwed up.

The long answer is that they shipped an /etc/inputrc that only works
for emacs mode editing, and then screwed all the vi users by setting
INPUTRC to /etc/inputrc in /etc/profile.

The short fix is to do one of the following: remove or rename
/etc/inputrc, set INPUTRC=~/.inputrc in ~/.bashrc (or .bash_profile,
but make sure you export it if you do), remove the assignment to
INPUTRC from /etc/profile, add

set keymap emacs

to the beginning of /etc/inputrc, or bracket the key bindings in
/etc/inputrc with these lines

$if mode=emacs
[...]
$endif

F7) Why do bash-2.05a and bash-2.05b fail to compile `printf.def' on
HP/UX 11.x?

HP/UX's support for long double is imperfect at best.

GCC will support it without problems, but the HP C library functions
like strtold(3) and printf(3) don't actually work with long doubles.
HP implemented a `long_double' type as a 4-element array of 32-bit
ints, and that is what the library functions use. The ANSI C
`long double' type is a 128-bit floating point scalar.

The easiest fix, until HP fixes things up, is to edit the generated
config.h and #undef the HAVE_LONG_DOUBLE line. After doing that,
the compilation should complete successfully.

Section G: How can I get bash to do certain common things?

G1) How can I get bash to read and display eight-bit characters?

This is a process requiring several steps.

First, you must ensure that the `physical' data path is a full eight
bits. For xterms, for example, the `vt100' resources `eightBitInput'
and `eightBitOutput' should be set to `true'.

Once you have set up an eight-bit path, you must tell the kernel and
tty driver to leave the eighth bit of characters alone when processing
keyboard input. Use `stty' to do this:

stty cs8 -istrip -parenb

For old BSD-style systems, you can use

stty pass8

You may also need

stty even odd

Finally, you need to tell readline that you will be inputting and
displaying eight-bit characters. You use readline variables to do
this. These variables can be set in your .inputrc or using the bash
`bind' builtin. Here's an example using `bind':

bash$ bind 'set convert-meta off'
bash$ bind 'set meta-flag on'
bash$ bind 'set output-meta on'

The `set' commands between the single quotes may also be placed
in ~/.inputrc.

G2) How do I write a function `x' to replace builtin command `x', but
still invoke the command from within the function?

This is why the `command' and `builtin' builtins exist. The
`command' builtin executes the command supplied as its first
argument, skipping over any function defined with that name. The
`builtin' builtin executes the builtin command given as its first
argument directly.

For example, to write a function to replace `cd' that writes the
hostname and current directory to an xterm title bar, use
something like the following:

cd()
{
builtin cd "$@" && xtitle "$HOST: $PWD"
}

This could also be written using `command' instead of `builtin';
the version above is marginally more efficient.

G3) How can I find the value of a shell variable whose name is the value
of another shell variable?

Versions of Bash newer than Bash-2.0 support this directly. You can use

${!var}

For example, the following sequence of commands will echo `z':

var1=var2
var2=z
echo ${!var1}

For sh compatibility, use the `eval' builtin. The important
thing to remember is that `eval' expands the arguments you give
it again, so you need to quote the parts of the arguments that
you want `eval' to act on.

For example, this expression prints the value of the last positional
parameter:

eval echo \"\$\{$#\}\"

The expansion of the quoted portions of this expression will be
deferred until `eval' runs, while the `$#' will be expanded
before `eval' is executed. In versions of bash later than bash-2.0,

echo ${!#}

does the same thing.

This is not the same thing as ksh93 `nameref' variables, though the syntax
is similar. I may add namerefs in a future bash version.

G4) How can I make the bash `time' reserved word print timing output that
looks like the output from my system's /usr/bin/time?

The bash command timing code looks for a variable `TIMEFORMAT' and
uses its value as a format string to decide how to display the
timing statistics.

The value of TIMEFORMAT is a string with `%' escapes expanded in a
fashion similar in spirit to printf(3). The manual page explains
the meanings of the escape sequences in the format string.

If TIMEFORMAT is not set, bash acts as if the following assignment had
been performed:

TIMEFORMAT=$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'

The POSIX.2 default time format (used by `time -p command') is

TIMEFORMAT=$'real %2R\nuser %2U\nsys %2S'

The BSD /usr/bin/time format can be emulated with:

TIMEFORMAT=$'\t%1R real\t%1U user\t%1S sys'

The System V /usr/bin/time format can be emulated with:

TIMEFORMAT=$'\nreal\t%1R\nuser\t%1U\nsys\t%1S'

The ksh format can be emulated with:

TIMEFORMAT=$'\nreal\t%2lR\nuser\t%2lU\nsys\t%2lS'

G5) How do I get the current directory into my prompt?

Bash provides a number of backslash-escape sequences which are expanded
when the prompt string (PS1 or PS2) is displayed. The full list is in
the manual page.

The \w expansion gives the full pathname of the current directory, with
a tilde (`~') substituted for the current value of $HOME. The \W
expansion gives the basename of the current directory. To put the full
pathname of the current directory into the path without any tilde
subsitution, use $PWD. Here are some examples:

PS1='\w$ ' # current directory with tilde
PS1='\W$ ' # basename of current directory
PS1='$PWD$ ' # full pathname of current directory

The single quotes are important in the final example to prevent $PWD from
being expanded when the assignment to PS1 is performed.

G6) How can I rename "*.foo" to "*.bar"?

Use the pattern removal functionality described in D3. The following `for'
loop will do the trick:

for f in *.foo; do
mv $f ${f%foo}bar
done

G7) How can I translate a filename from uppercase to lowercase?

The script examples/functions/lowercase, originally written by John DuBois,
will do the trick. The converse is left as an exercise.

G8) How can I write a filename expansion (globbing) pattern that will match
all files in the current directory except "." and ".."?

You must have set the `extglob' shell option using `shopt -s extglob' to use
this:

echo .!(.|) *

A solution that works without extended globbing is given in the Unix Shell
FAQ, posted periodically to comp.unix.shell.

Section H: Where do I go from here?

H1) How do I report bugs in bash, and where should I look for fixes and
advice?

Use the `bashbug' script to report bugs. It is built and
installed at the same time as bash. It provides a standard
template for reporting a problem and automatically includes
information about your configuration and build environment.

`bashbug' sends its reports to bug-bash@gnu.org, which
is a large mailing list gatewayed to the usenet newsgroup gnu.bash.bug.

Bug fixes, answers to questions, and announcements of new releases
are all posted to gnu.bash.bug. Discussions concerning bash features
and problems also take place there.

To reach the bash maintainers directly, send mail to
bash-maintainers@gnu.org.

H2) What kind of bash documentation is there?

First, look in the doc directory in the bash distribution. It should
contain at least the following files:

bash.1 an extensive, thorough Unix-style manual page
builtins.1 a manual page covering just bash builtin commands
bashref.texi a reference manual in GNU tex`info format
bashref.info an info version of the reference manual
FAQ this file
article.ms text of an article written for The Linux Journal
readline.3 a man page describing readline

Postscript, HTML, and ASCII files created from the above source are
available in the documentation distribution.

There is additional documentation available for anonymous FTP from host
ftp.cwru.edu in the `pub/bash' directory.

Cameron Newham and Bill Rosenblatt have written a book on bash, published
by O'Reilly and Associates. The book is based on Bill Rosenblatt's Korn
Shell book. The title is ``Learning the Bash Shell'', and the ISBN number
is 1-56592-147-X. Look for it in fine bookstores near you. This book
covers bash-1.14, but has an appendix describing some of the new features
in bash-2.0.

A second edition of this book is available, published in January, 1998.
The ISBN number is 1-56592-347-2. Look for it in the same fine bookstores
or on the web.

The GNU Bash Reference Manual has been published as a printed book by
Network Theory Ltd (Paperback, ISBN: 0-9541617-7-7, Feb 2003). It covers
bash-2.0 and is available from most online bookstores (see
http://www.network-theory.co.uk/bash/manual/ for details). The publisher
will donate $1 to the Free Software Foundation for each copy sold.

H3) What's coming in future versions?

These are features I hope to include in a future version of bash.

a better bash debugger (a minimally-tested version is included with bash-2.05b)
associative arrays
co-processes, but with a new-style syntax that looks like function declaration

H4) What's on the bash `wish list' for future versions?

These are features that may or may not appear in a future version of bash.

breaking some of the shell functionality into embeddable libraries
a module system like zsh's, using dynamic loading like builtins
better internationalization using GNU `gettext'
date-stamped command history
a bash programmer's guide with a chapter on creating loadable builtins
a better loadable interface to perl with access to the shell builtins and
variables (contributions gratefully accepted)
ksh93-like `nameref' variables
ksh93-like `+=' variable assignment operator
ksh93-like `xx.yy' variables (including some of the .sh.* variables) and
associated disipline functions
Some of the new ksh93 pattern matching operators, like backreferencing

H5) When will the next release appear?

The next version will appear sometime in 2003. Never make predictions.


This document is Copyright 1995-2003 by Chester Ramey.

Permission is hereby granted, without written agreement and
without license or royalty fees, to use, copy, and distribute
this document for any purpose, provided that the above copyright
notice appears in all copies of this document and that the
contents of this document remain unaltered.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
( ``Discere est Dolere'' -- chet )
Live...Laugh...Love
Chet Ramey, ITS, CWRU chet@po.cwru.edu http://tiswww.tis.cwru.edu/~chet/
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
( ``Discere est Dolere'' -- chet )
Live...Laugh...Love
Chet Ramey, ITS, CWRU chet@po.cwru.edu http://tiswww.tis.cwru.edu/~chet/