help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] prompt help


From: Greg Wooledge
Subject: Re: [Help-bash] prompt help
Date: Mon, 13 Feb 2012 08:31:11 -0500
User-agent: Mutt/1.4.2.3i

On Mon, Feb 13, 2012 at 01:37:39PM +0300, Mihamina Rakotomandimby wrote:
> Hi all,
> 
> Running Bash 4.2.20, I would like to have a prompt composed by the first 
> letters of the base path, excluding the last one.
> 
> 
> Example:
> - /u/l/bin if I'm in /usr/local/bin
> - /v/w/h/my-website if I'm in /var/www/html/my-website
> - /h/mihamina if I'm in /home/mihamina

There are a couple approaches that will work for this.  Both of them
involve setting variables in your dot-files (~/.bashrc or ~/.bash_profile
or ~/.profile).  There are two variables that govern what bash does
with the prompt: PROMPT_COMMAND and PS1.  They are very different, but
they can be made to work together.

PS1 is the variable that holds the actual prompt.  It is subject to some
interpretation by the shell at the time the prompt is about to be
displayed, so it's capable of holding some dynamic content on its own.
Specifically, any parameter expansions and command substitutions in PS1
will occur when it is evaluated.  This means we can, for example, put
the current working directory in the prompt by doing:

PS1='$PWD\$ '

and $PWD will be evaluated at prompt display time.

Likewise, we can perform function calls:

PS1='$(myfunc "$PWD")\$ '

where myfunc must obviously be defined within the current shell so that
it can be called when PS1 is evaluated.  However, the command substitution
involves forking a child process, which means it's SLOW.  If you don't
mind a little delay every time bash draws the prompt, then this approach
is sufficient, and you can go ahead with it.

The alternative approach involves setting variables for PS1 to evaluate.
PS1 cannot perform variable assignments on its own, but PROMPT_COMMAND
can.  Therefore, this second approach uses PROMPT_COMMAND to set a variable
for PS1 to use.  The advantage of this more complicated approach is that
it doesn't need to use command substitution, which means it doesn't need
to fork, which means it's much faster.

PROMPT_COMMAND='IFS=/; unset b; read -ra a <<< "$PWD"; address@hidden;
  for ((i=0; i<n-1; i++)); do b+=("${a[i]:0:1}"); done; b+=("${a[i]}");
  mypwd="${b[*]}"; unset IFS'
PS1='$mypwd\$ '

What this is doing, a bit messily, is: split the $PWD variable into
elements using / as the delimiter.  Iterate through all but the last
of these elements, and populate a new array with the first character of
each element.  Stick the entire last element on the new array.  Then
join them back together into a new string, still using / as the delimiter
(first char of IFS).  Then unset IFS to return us to normal.

This leaves arrays a and b, as well as string variables i, n and mypwd,
in the global variable space.  Hence "a bit messily" above.  If that's
a concern, you could write a function to create a local scope for the
variables a, b, i and n, but let it write mypwd into the global space
(it has to be there for PS1 to see it).  Or you could use temporary
variables whose names are less likely to collide with other variables.
Or you could just leave it as is.

> Of course, this could lead to some errors and confusion, but it's useful 
> for my particular use case, and if I want to explicitely print the 
> current directory, I'll just have to "cwd".

You mean pwd.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]