[comp.unix.questions] The whole prompt string thing

marcos@caus-dp.UUCP (Marcos R. Della) (11/30/87)

In article <207@jc3b21.UUCP>, jra@jc3b21.UUCP (Jay R. Ashworth) writes:
> In article <9354@ufcsv.cis.ufl.EDU>, esj@beach.cis.ufl.edu
> > In article <137@anumb.UUCP> eao@anumb.UUCP (e.a.olson) writes:
> > >	no - cd is done in the shell itself.    Not the kernel.
> > >	Well, of course, everything interesting is done in the kernel;
> > >					eric olson, ihnp4!mvuxq!eao
> > 
> > What you need to do is modify it (bourne shell) to evaluate that variable
> > each time it uses it. Best-o-Luck.
> > Eric S. Johnson II Internet: esj@beach.cis.ufl.edu University of Florida 
> 
> ... I may get the chance to play with all this here
> in a while, but if anyone can save me the trouble, go right ahead.

Well, after mounds of responses from lots of people (I think that we have
around 30+ messages on this subject floating around) and lots of mail from
all over the place, so far we have gotten...

...nowhere. There are lots of interesting ideas and designs, but so far,
nothing is working on this little problem. Has anyone out there actually
done this and gotten it to work?

We have tried everything that has come over the net, put some together,
taken others apart, mishmashed them all around and come up with the big
zilch on this problem. I never realized that this would become such a
problem. So...

Are there any OTHER suggestions that might shed some light on the matter?

Marcos Della
Daniel Harris

-- 
...!csustan ->!polyslo!caus-dp!marcos		    | Whatever I said doesn't
...!sdsu ---/	Marcos R. Della			    | mean diddly as I forgot
...!csun --/	Smail:PO Box 8104 SLO,CA 93403-8104 | it even before finishing
...!dmsd -/	Tele: (805) 544-4900		    | typing it all out!!! :-)

gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/02/87)

In article <305@caus-dp.UUCP> marcos@caus-dp.UUCP (Marcos R. Della) writes:
>... There are lots of interesting ideas and designs, but so far,
>nothing is working on this little problem. Has anyone out there actually
>done this and gotten it to work?

Dammit, didn't you read my posting?  We do this all the time here.
I explained what is required and don't feel like repeating myself.

randy@umn-cs.cs.umn.edu (Randy Orrison) (12/03/87)

In article <6773@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn) writes:
>In article <305@caus-dp.UUCP> marcos@caus-dp.UUCP (Marcos R. Della) writes:
>>... There are lots of interesting ideas and designs, but so far,
>>nothing is working on this little problem. Has anyone out there actually
>>done this and gotten it to work?
>
>Dammit, didn't you read my posting?  We do this all the time here.
>I explained what is required and don't feel like repeating myself.

Come on people, settle down.  The problem is obvious:

Marcos has an older version of the bourne shell.

	Marcos:  YOU CAN'T DO IT.  Get a newer version of sh or get ksh or
		 get csh.

	Doug:	 SETTLE DOWN.  The poor guy doesn't know why what everyone
		 says works won't work for him.  Give him a break.

I haven't heard anyone talking about versions of sh or ksh here.  What versions
of each are needed to do these things?  Obviously, all versions don't do command
evaluation or variable substitution when displaying the prompt.

	-randy
-- 
Randy Orrison, University of Minnesota School of Mathematics  | May the smiley
UUCP:	{ihnp4, seismo!rutgers, sun}!umn-cs!randy	      |      O__\,
ARPA:	randy@ux.acss.umn.edu		BITNET: randy@umnacca |      O  /'
Disclaimer:  No one is silly enough to pay me to do this.     |  be with you!

mikep@ism780c.UUCP (Michael A. Petonic) (12/03/87)

Ok, how about a detailed step by step procedure (but not too
specific as I don't have the source in front of me).  it seems
obvious that the bourne shell needs to be modified.  Now, if you want
the prompt to ALWAYS show the current working directory at the beginning,
it's a simple matter.  Just modify the shell to print it out when it
prints a prompt.  Probably only one or fifteen lines of code.

Now, if you want to have a special sequence in $PS1 to indicate
that you want the cwd there, it's a different matter...

Say you want %P to represent the path in $PS1.  Here's how I would
go about it...

1) First, make another char star that will point to an internal version
of PS1.  This is to contain PS1 as it is printed out (as a prompt).

2) Parse the value for PS1 into the internal PS1 pointer (include
the cwd iff PS1 has %P in it).

3) Modify the variable setting section of the shell to change the internal
PS1 if PS1 is modified.  This includes a call to getcwd(3) (which
is VERY expensive) if the external PS1 contains %P in it.

4) Modify the section of code of the "cd" command to reset the internal PS1
(if the external PS1 contains %P) based on what the argument is to the
cd command (and to the cwd(2) call).  Instead of having it parse
through all the possible "..", etc., you could make things easier by
doing another call to getcwd(3), but again, that's expensive.

5) Modify the part of the shell that prints the prompt to instead print
out the internal version of PS1.

* Note:  This was thought up in only about 3 minutes, so it isn't the best
way.  Another way is to just store the current working directory in
an internal variable instead of an internal PS1.  In anycase, this
is just ONE of the many ways that this problem can be solved.

What the hell's so hard about it?  I know a guy who's in the
ARMY who did this to the bourne shell (it always printed the
prompt, not the flexible method I described), so if he did it,
I'm sure it's not that tough.

Thre are two alternate solutions:  Use the Korn Shell (preferred!) or
use Tim Smith's (also of ISC) solution:  $ PS1="." which
ALWAYS prints out the current working directory.

-MikeP

gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/03/87)

In article <3045@umn-cs.cs.umn.edu> randy@umn-cs.UUCP (Randy Orrison) writes:
>I haven't heard anyone talking about versions of sh or ksh here.  What versions
>of each are needed to do these things?  Obviously, all versions don't do command
>evaluation or variable substitution when displaying the prompt.

You do NOT need for the shell to do tricks while printing the value of PS1,
although if your shell does that then it can be used to do what was requested.
Any shell that supports shell functions will support user definition of a
command to be used instead of the built-in "cd", that will not only perform
cd but also update PS1.  UNIX System V shells starting with Release 2.0 have
such support.  For such a function to also be called "cd", so you can't
forget to use the new function and mistakenly invoke just the built-in,
you need a shell that permits functions to redefine builtin names; the UNIX
System V shells do not permit this.  However, if you have a valid source
license you can obtain the BRL version of the SVR2 Bourne shell, which has
this and much more.

arnold@emory.uucp (Arnold D. Robbins {EUCC}) (12/03/87)

In article <305@caus-dp.UUCP> marcos@caus-dp.UUCP (Marcos R. Della) writes:
[ ... we have gotten ]
>...nowhere. There are lots of interesting ideas and designs, but so far,
>nothing is working on this little problem. Has anyone out there actually
>done this and gotten it to work?

OK, Off the top of the head of an experienced shell hacker: In main.c
there is a line that says:

			prs(ps1nod.namval);

Change it to read

			prs (macro (ps1nod.namval));

Recompile and reinstall the shell. Then, in your .profile you
can say

	PS1='`pwd`> '

Note that this will run pwd for every prompt! If you have more patience,
add in the shell code a PWD shell variable that gets set every time you do
a 'cd', and then set PS1='$PWD> '. Note the single quotes.

If you have the S5R2 or later shell where pwd is built-in, then running pwd
each time is not such a big problem.

Or you could add your own pr_prompt function, put pr_prompt (ps1nod.namval)
into the code, and define your own semantics for printing the prompt.

In all cases, for BSD /bin/sh or S5R[23] /bin/sh, you have to modify the
code to get the result. Ksh already does things this way, so if you
have ksh it's not a problem.

Usual disclaimers apply; the suggestions above are untested.
-- 
Arnold Robbins
ARPA, CSNET:	arnold@emory.ARPA	BITNET: arnold@emory
UUCP: { decvax, gatech, }!emory!arnold	DOMAIN: arnold@emory.edu (soon)
	``csh: just say NO!''

ray3rd@ssc-vax.UUCP (12/03/87)

In article <6773@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
> In article <305@caus-dp.UUCP> marcos@caus-dp.UUCP (Marcos R. Della) writes:
> >... There are lots of interesting ideas and designs, but so far,
> >nothing is working on this little problem. Has anyone out there actually
> >done this and gotten it to work?

Ok, here is what I use to get a new prompt each time I 'cd'

(First of all, you MUST log into csh, I know, you want a sh answer)


         set prompt="`hostname` `tty` `pwd`> "
         alias cd \
          'cd \!$;set prompt="`hostname` `tty` `pwd`> "'


I realize that this doesn't satisfy the desire for a 'trick' in the
Bourne shell, but I'm getting dizzy reading all the requests, and
nothing shows up.  For what it's worth.....


-- 
Ray E. Saddler III       CAD Support and Administration |    __  __ __       __
Boeing Aerospace Company Ballistic Systems Division     |   / / / //   //| // 
P.O. Box 3999 M.S. 3R-05 Kent Space Center East         |  /-< / //-  // |// _
Seattle, Wa. 98124  USA  (206)657-2824 or (206)657-3369 | /__//_//__ //  //__/

rupley@arizona.edu (John Rupley) (12/04/87)

In article <305@caus-dp.UUCP>, marcos@caus-dp.UUCP (Marcos R. Della) writes:
> Well, after mounds of responses from lots of people (I think that we have
> around 30+ messages on this subject floating around) and lots of mail from
> all over the place, so far we have gotten...
> 
> ...nowhere. There are lots of interesting ideas and designs, but so far,
> nothing is working on this little problem. Has anyone out there actually
> done this and gotten it to work?
> 
> We have tried everything that has come over the net, put some together,
> taken others apart, mishmashed them all around and come up with the big
> zilch on this problem. I never realized that this would become such a
> problem. So...
> 
> Are there any OTHER suggestions that might shed some light on the matter?
> 
> Marcos Della
> Daniel Harris

You want to set PS1="current_directory_path", and you want to do this 
with one command, that also changes your working directory (that is, 
you understandably do not want to type in a sequence of three commands 
each time you change directory). If I remember you have a Xenix SysV 
look-a-like.  It probably does not allow the exporting of shell 
function names.  And you cannot redefine a builtin like cd.  So you 
try to use a shell script, call it "cwd" or whatever, in place of the 
builtin, cd.  However, a shell script is executed as a forked process, 
so a change in PS1 done in it will not affect the parent and the change 
is "lost" when the script terminates. Thus the correct answer, which 
you have been given, is that you cannot do what you want, except by 
modifying the sh source or worse yet, the kernel.

Nevetheless, you can have the <APPEARANCE> of keeping the change if you 
are willing to exec a new interactive shell as the last script command.  
You do not terminate the script until you terminate (^d or whatever) 
the new shell.  By using "exec sh -i" you overlay the script process by 
the new shell.  Thus you still have only the one child process 
associated with script execution, and this child is the new interactive 
shell.  

I threaded through the "PS1" responses, and it seems to me that several 
contributors implied the above, which seems a pretty obvious 
work-around that does what you want.  Many of the other responses 
appear correct but relied on functionality probably not found for the 
Xenix Bourne shell.

So if you really want the prompt to contain the working directory, and 
you are willing to retrain your fingers to use a new acronym to change 
directory, and you are willing to spawn a new interactive shell at each 
directory change, try the following (which I tested on a simple SysV 
Bourne shell (Microport SysV/AT2.2)  and a Bourne shell variant under 
BSD4.3 (under BSD I had to sh the command)):

++++++++++++++++bourne shell script+++++++++++
#!sh 
#usage: cwd  [directory_on_cdpath | full_directory_path]
#cd to directory on command line (or $home if no argument);
#set prompt PS1=dirctory_path followed by one or more ">"'s, 
#the number of which indicates the number of invocations of this command,
#which equals the depth of the shell set;
#a new shell is spawned each time cwd is invoked;
#when moving back through the shells (by ^d=eof), 
#the login shell can be recognized by the default PS1 prompt
#note: should error exit on a bad argument, doing nothing -- 
#if not, start up with:
# sh -c "cd $1"
# if [ $? -ne 0 ] exit 1

cd $1
PS1=`pwd`">"`echo $PS1|sed -e '/^[^>]*/s///'`
export PS1
exec sh	-i
+++++++++++++++++end shell script+++++++++

A four-line script is pretty simple, but I am not sure that having a 
prompt with the current directory is worth the shells.  If you feel it 
is, you might want to add frills like doing a string search on a file 
of the directories within your domain of the file hierarchy, which
you can have cron create by executing find at 6am.  The following
script I do find useful:

++++++++++++++++++another shell script+++++
#!sh cwdir
#usage: cwdir [-p] string__matching_directory_path
#cd
 to directory with path matching string on command line
#option: -p  => interactively pick from set of matches
#		("pick" from Kernighan and Pike, or equivalent)
#set PS1 according to new directory path

DIRLIST="/usr/local/opsys/filelists/dirlist"
if [ $1 = "-p" ]
then
	shift
	STRING=`pick \`egrep "$1[^\/]*\$" $DIRLIST\``
else
	STRING=`egrep "$1[^\/]*\$" $DIRLIST`
fi
if [ "x$STRING" != "x" ]
then
	cd $STRING
	PS1=`pwd`">"`echo $PS1|sed -e '/^[^>]*/s///'`
	export PS1
	exec sh -i
fi
+++++++++++++++++end shell script+++++++++

Hope this helps,

John Rupley
 uucp: ..{ihnp4 | hao!noao}!arizona!rupley!local
 internet: rupley!local@megaron.arizona.edu
 telex: 9103508679(JARJAR)
 (H) 30 Calle Belleza, Tucson AZ 85716 - (602) 325-4533
 (O) Dept. Biochemistry, Univ. Arizona, Tucson AZ 85721 - (602) 621-3929

allbery@ncoast.UUCP (12/05/87)

As quoted from <305@caus-dp.UUCP> by marcos@caus-dp.UUCP (Marcos R. Della):
+---------------
| Well, after mounds of responses from lots of people (I think that we have
| around 30+ messages on this subject floating around) and lots of mail from
| all over the place, so far we have gotten...
| 
| ...nowhere. There are lots of interesting ideas and designs, but so far,
| nothing is working on this little problem. Has anyone out there actually
| done this and gotten it to work?
+---------------

Back when I modified someone's System V sh on a consulting job, I came up
with a way to do this.  I didn't evaluate PS1, instead I set up a variable
PS1FUNC, which overrode PS1; if it existed, it was executed as a shell
command (see the way the "trap" builtin is implemented as an example of how
to do this).  I daresay there are better ways, but I'm not precisely a shell
hacker; that was the first and last time that I have, legitimately or other-
wise, had access to shell source.  (Nor am I interested in non-legitimate
access; if I really want to play with shell source, I'll use the PD shell
from Minix, otherwise I'm quite satisfied with ksh on my 3B1....)
-- 
Brandon S. Allbery		      necntc!ncoast!allbery@harvard.harvard.edu
 {hoptoad,harvard!necntc,cbosgd,sun!mandrill!hal,uunet!hnsurg3}!ncoast!allbery
			Moderator of comp.sources.misc

eichin@athena.mit.edu (Mark W. Eichin) (12/06/87)

Another way (popular here) is to alias cd (and back and others) to set
the prompt themselves...
					Mark Eichin
					<eichin@athena.mit.edu>

ccs6277@ritcv.UUCP (Clifford C. Skolnick) (12/06/87)

Here is how I've been putting my path name into my command prompt for
my Unix PC in Korn Shell


------------- lines in .kshrc ---------

SYSTEM=`system`

PS1="$SYSTEM `pwd` [!]: "

alias oldcd=cd
alias cd=newcd

newcd() {
 oldcd $*
 PS1="$SYSTEM `pwd` [!]: "
}
------------- end of .kshrc  ----------

 Cliff Skolnick
 ...rochester!ritcv!ccs6277
 ...rochester!ritcv!ritcsh!sabin!lazlo!{root|ccs}

ok@quintus.UUCP (Richard A. O'Keefe) (12/07/87)

The task is to come up with some form of Bourne shell command such that
	{initial stuff} {arg} {final stuff}
has the same effect as
	cd {arg}
except that in addition it sets PS1 to something like "`pwd` > ".
In this message I provide two solutions which should work in any
reasonable Bourne shell (no aliases or shell functions).

Since the directory is to be changed, the command ought to be executed
by the current shell.  The obvious thing to try is the "dot" command:
	. file
reads commands from file and executes them in the current shell.
The whole point of the "dot" command is to set environment variables.
Unfortunately, you can't pass positional parameters this way, so you
have to use environment variables.  Let's reserve the variable "d"
for this.  Letting the file be called "sd", the total command will be
	d={arg} . sd
It would be nice if
	. sd
acted like cd without an argument.  The rest is almost obvious.

# beginning of script to make sd
cat <<'EOF' >sd
cd ${d:-$HOME}
PS1="`pwd` > "
unset d
EOF	
chmod a=rx sd
exit
# end of script to make sd

Why the "unset" command?  Well, there is a fine point about keyword
parameters which is not in the manual.  The VSID says (Vol 2, p 105):
	The environment for any _simple-command_ may be augmented by
	prefixing it with one or more assignments to parameters.  Thus:
		TERM=123 cmd
		(export TERM; TERM=123; cmd)
	(where cmd uses the value of the environmental variable TERM) are
	equivalent as far as the execution of cmd is concerned.
The trouble with "dot" is that it is a "special command"; the SVID is
not clear about in which respects "special commands" are
_simple-commands_; for example in SVR1 special commands couldn't have
I/O redirection.  (In SVR2 and SVR3 they can.)  It turns out that
there is a difference between "special commands" and others with
respect to keyword parameters.  Keyword parameters are allowed on ANY
_simple-command_, but
	var=val PROGRAM		binds var to val for PROGRAM
				and does not change its global value.
				(let ((var val)) PROGRAM)

	var=val SPECIAL		permanently sets var to val and
				then executes SPECIAL
				(progn (setq var val) SPECIAL)
This is true in the 4.2, V.2, and V.3 systems I have tried.
The relevance to sd is that
	d=directory . sd
permanently changes d, so a later sd can't tell whether there was a
d keyword argument or not.  So I've made sd remove the binding for
d.  (unset arrived in SVR2, so on earlier Bourne shells, just forget
it and put up with always specifying d.)

This is not pretty, and it seems to me that keywords parameters should
be local to special commands as well as to ordinary programs, just as
you can now redirect I/O for special commands too.

Summary:
	d=directory . sd
should do the job in any reasonable Bourne shell.
It looks odd, but can typically be typed without touching the shift key.

There is another possibility.
	cat <<'EOF' >sd2
	cd ${1:-$HOME}
	here=`pwd`
	echo "PS1='$here > ' ; cd $here" 
	EOF
You execute this with eval:
	eval `sd2 directory`
You have to use the shift key for this one, but it is a general technique
for doing anything you like and then updating the parent shell.

I normally use a SUN, and have an alias set up which puts the current
hostname and current directory into the title-bar of a window.  Some
terminals have a mode-line which can be set, and either of these methods
could be used to set the mode-line rather than the prompt string.

kers@otter.HP.COM (Christopher Dollin) (12/07/87)

Re: the prompt string thing.

I admit it. I'm new to the net. It's not really the right sort of question.
But ... why do people want to display the current directory in their prompt
string anyway? What am I missing? Is it really worth all the effort people
are devoting to it, or is it just the challenge of bending grotty pieces of
software to our needs that prvieds the attraction?

Puzzled,
Kers.

jack@swlabs.UUCP (Jack Bonn) (12/08/87)

In article <1170001@otter.HP.COM>, kers@otter.HP.COM (Christopher Dollin) writes:
> ... why do people want to display the current directory in their prompt
> string anyway? What am I missing? Is it really worth all the effort people
> are devoting to it, or is it just the challenge of bending grotty pieces of
> software to our needs that prvieds the attraction?

I think that one reason for this is that the unix community is forever 
boasting how much better/easier-to-expand/more-modular their system is in 
comparison with others, especially that Messy-DOS stuff.

Yet in DOS, to set the prompt to the current working directory (a sometimes
convenient thing to do), one simply issues the command PROMPT $p.  It is not 
quite as easy as this in unix.
-- 
Jack Bonn, <> Software Labs, Ltd, Box 451, Easton CT  06612
uunet!swlabs!jack

gp@picuxa.UUCP (Greg Pasquariello X1190) (12/08/87)

In article <1170001@otter.HP.COM>, kers@otter.HP.COM (Christopher Dollin) writes:
> But ... why do people want to display the current directory in their prompt
> string anyway? 

	It is basically an easy way to always know where you are.

> are devoting to it, or is it just the challenge of bending grotty pieces of
> software to our needs that prvieds the attraction?

	Yes! :-)

hartzell@boulder.Colorado.EDU (George Hartzell) (12/10/87)

In article <1410@swlabs.UUCP> jack@swlabs.UUCP (Jack Bonn) writes:
>
>Yet in DOS, to set the prompt to the current working directory (a sometimes
>convenient thing to do), one simply issues the command PROMPT $p.  It is not 
>quite as easy as this in unix.
>-- 
>Jack Bonn, <> Software Labs, Ltd, Box 451, Easton CT  06612
>uunet!swlabs!jack

At the risk of starting another Crusade, if you are using the latest version 
of the tenex c shell you can set your prompt to the full path name of the
current working directory with:
set prompt="%d"
and you can set it to the tail of the full path with:
set prompt="%c"

Isn't it nice to be able to choose your shell?
g.

George Hartzell			                 (303) 492-4535
MCD Biology, University of Colorado-Boulder, Boulder, CO 80309
hartzell@Boulder.Colorado.EDU  ..!{hao,nbires}!boulder!hartzell