[comp.unix.shell] KSH-How do I make a variable run a function upon invocation?

jbn35564@uxa.cso.uiuc.edu (J.B. Nicholson) (04/10/91)

In KSH I want to make ${PS1} take on a value where it executes a function called
PS1, but not take on the output from the function itself.  Here's what I mean:

function PS1 {
shrunkhome=${PWD%${HOME}/}
case ${shrunkhome} in
        ${HOME})        shrunkhome=\~/ ;;
esac
HOSTNAME=$(hostname)
print -n '<'${USER}'@'${HOSTNAME%%.*}':'${shrunkhome}'> ' ;;
}

...then I want to define...

export PS1=$(PS1)

but that only works the first time I use ${PS1}.  I'd like to define it as:

export PS1=[just run the function called](PS1)

but I don't know how to make that definition.  I've tried having an alias
for cd:

alias -x cd='_cd'

and a function (defined before that alias was set) called _cd that basically
assigns ${PS1} to the right value somewhat similar to above, except passing
arguments to the REAL cd program (to maintain compatibility) but every time
I access cd, won't this function _cd run?  Also, all my error messages come
from _cd and not cd.  That's rather annoying to me.  Anyways, I figure keeping
this whole thing inside ${PS1} would not void any warranties, cause any
mayhem or incompatibilities or whatever. :-)

So, basically what I'm asking is:  How do I do this?

Thanks in advance,
Jeff
--
+----------------------------------------------------------------------------+
| "If you hear an onion ring - answer it."                    J.B. Nicholson |
+----------------------------------------------------------------------------+
| jeffo@uiuc.edu (Internet)              These opinions are mine, that's all.|
+----------------------------------------------------------------------------+

asg@sage.cc.purdue.edu (Bruce Varney) (04/10/91)

In article <1991Apr10.035042.3008@ux1.cso.uiuc.edu> jeffo@uiuc.edu writes:
}In KSH I want to make ${PS1} take on a value where it executes a function called
}PS1, but not take on the output from the function itself.  Here's what I mean:
}
}alias -x cd='_cd'
}
}and a function (defined before that alias was set) called _cd that basically
}assigns ${PS1} to the right value somewhat similar to above, except passing
}arguments to the REAL cd program (to maintain compatibility) but every time
}I access cd, won't this function _cd run?  Also, all my error messages come
}Thanks in advance,
}  Jeff
Here is the scoop - there are two possibilities
The first and easiest (IMHO) is to switch shells to bash. bash has a variable
PROMPT_COMMAND which is a command to run before the prompt is printed.
Thus you could do something line
PS1="\$WD ->"
PROMPT_COMMAND = "WD = `working_dir`"
working_dir() {
whatever you use to prune the dir name
}
Course if you are stuck on ksh, this will also work. Note that it will not work
with csh as ksh and csh handle aliases different
alias -x x=cd
alias -x cd='cd_help'
cd_help() {
whatever you use to prune the dir name
x $1
}

that will work just fine (or should). 
		Hope this helps
			As Always
			   The Grand Master

---------
                                   ###             ##
Courtesy of Bruce Varney           ###               #
aka -> The Grand Master                               #
asg@sage.cc.purdue.edu             ###    #####       #
PUCC                               ###                #
;-)                                 #                #
;'>                                #               ##

jbn35564@uxa.cso.uiuc.edu (J.B. Nicholson) (04/11/91)

In <10009@mentor.cc.purdue.edu> asg@sage.cc.purdue.edu (Bruce Varney) writes:

>Here is the scoop - there are two possibilities
>The first and easiest (IMHO) is to switch shells to bash. bash has a variable
>PROMPT_COMMAND which is a command to run before the prompt is printed.

This sounds very nice, but BASH has no documentation (that I know of) beyond
the helpscreen, which isn't like having at least a long man page at your
fingertips.  When more docs become available for BASH, I'll take a serious look
at it, 'till then, I'll have to stick with KSH.

>Course if you are stuck on ksh, this will also work. Note that it will not work
>with csh as ksh and csh handle aliases different
[...description deleted...]
>that will work just fine (or should). 
>		Hope this helps
>			As Always
>			   The Grand Master

Well, I've tried using that idea:

function simpleattempt {
print -n 'this is coming from simpleattempt()'
}

and then:

PS1='simpleattempt'

will make your prompt:
simpleattempt

so, I tried:

PS1=$(simpleattempt)

But that makes ${PS1}:
this is coming from simpleattempt()

and I need ${PS1} to retain the value of '$(simpleattempt)' or whatever the
command is to make a function run.  I don't want the output of simpleattempt()
to be substituted into the contents of ${PS1}, I just want ${PS1} to run
that function whenever ${PS1} is called.

I tried a method of doing this where cd is aliased to a function that does all
the calculations necessary for the prompt string and performs the regular cd
command (called _cd), but I got error messages from _cd and not cd.  Also, if
anything was run to reference the KSH's cd command, it would go through all my
prompt string stuff slowing it down a lot.

Therefore, I'm trying to keep all this prompt string modification inside of
${PS1}.

If I just had a way for ${PS1} to run a function without changing the value of
${PS1}, I'd be set.

Jeff
--
+----------------------------------------------------------------------------+
| "If you hear an onion ring - answer it."                    J.B. Nicholson |
+----------------------------------------------------------------------------+
| jeffo@uiuc.edu (Internet)              These opinions are mine, that's all.|
+----------------------------------------------------------------------------+

asg@sage.cc.purdue.edu (Bruce Varney) (04/11/91)

In article <1991Apr10.190259.9524@ux1.cso.uiuc.edu> jeffo@uiuc.edu writes:
}In <10009@mentor.cc.purdue.edu> asg@sage.cc.purdue.edu (Bruce Varney) writes:
}
}>Here is the scoop - there are two possibilities
}>The first and easiest (IMHO) is to switch shells to bash. bash has a variable
}>PROMPT_COMMAND which is a command to run before the prompt is printed.
}
}This sounds very nice, but BASH has no documentation (that I know of) beyond
}the helpscreen, which isn't like having at least a long man page at your
}fingertips.  When more docs become available for BASH, I'll take a serious look
}at it, 'till then, I'll have to stick with KSH.
Wrong Wrong Wrong
There is a man page for bash. 
Tell you what - ftp to slc2.ins.cwru.edu and get the file
/pub/(This is either gnu or bash)/bash-1.07.cwru.tar.Z
uncompress and untar it
It will contain the source for bash 1.07 as well as the man page
which is in documentation/bash.1  Just do a:
cd documentation
mroff -man bash.1 > bash.man
more bash.man
and you will get to read the bash man page.
Most of bashes functionality is just like KSH. The only differences are
the additions ( and the loss of select and let, but $[] replaces let).

}
}>Course if you are stuck on ksh, this will also work. Note that it will not work
}>with csh as ksh and csh handle aliases different
}[...description deleted...]
}>that will work just fine (or should). 
}>		Hope this helps
}>			As Always
}>			   The Grand Master
}
}Well, I've tried using that idea:
}
}function simpleattempt {
}print -n 'this is coming from simpleattempt()'
}}
}
}and then:
}
}PS1='simpleattempt'
}
}will make your prompt:
}simpleattempt
}
}so, I tried:
}
}PS1=$(simpleattempt)
try
PS1=\$(simpleattempt)

}
}But that makes ${PS1}:
}this is coming from simpleattempt()
}
}to be substituted into the contents of ${PS1}, I just want ${PS1} to run
}that function whenever ${PS1} is called.

As I said, you can use the PROMPT_COMMAND variable in bash - just look
it up in the man page ;-)

}
}I tried a method of doing this where cd is aliased to a function that does all
}the calculations necessary for the prompt string and performs the regular cd
}command (called _cd), but I got error messages from _cd and not cd.  Also, if
}anything was run to reference the KSH's cd command, it would go through all my
}prompt string stuff slowing it down a lot.

So try bash!!!

---------
                                   ###             ##
Courtesy of Bruce Varney           ###               #
aka -> The Grand Master                               #
asg@sage.cc.purdue.edu             ###    #####       #
PUCC                               ###                #
;-)                                 #                #
;'>                                #               ##

chet@odin.INS.CWRU.Edu (Chet Ramey) (04/11/91)

In article <10052@mentor.cc.purdue.edu> asg@sage.cc.purdue.edu (Bruce Varney) writes:

>Most of bashes functionality is just like KSH. The only differences are
>the additions ( and the loss of select and let, but $[] replaces let).

The version of bash that Bruce describes does have `let'.

Chet
-- 
Chet Ramey			  Internet: chet@po.CWRU.Edu
Case Western Reserve University	  NeXT Mail: chet@macbeth.INS.CWRU.Edu

``Now,  somehow we've brought our sins back physically -- and they're pissed.''

eric@ms.uky.edu (Eric H. Herrin II) (04/12/91)

jbn35564@uxa.cso.uiuc.edu (J.B. Nicholson) writes:

>In KSH I want to make ${PS1} take on a value where it executes a function called
>PS1, but not take on the output from the function itself.  Here's what I mean:

>function PS1 {
>shrunkhome=${PWD%${HOME}/}
>case ${shrunkhome} in
>        ${HOME})        shrunkhome=\~/ ;;
>esac
>HOSTNAME=$(hostname)
>print -n '<'${USER}'@'${HOSTNAME%%.*}':'${shrunkhome}'> ' ;;
>}

Try this:

function _cd {
   unalias cd
   cd $1
   alias cd=_cd
   if [ "${PWD#${HOME}}" != "${PWD}" ]
   then
           PS1='"${USER}@${HOSTNAME%%.*}:~/${PWD#${HOME}}> "'
   else
           PS1='"${USER}@${HOSTNAME%%.*}:${PWD}> "'
   fi
}

and alias cd to '_cd' as you suggested in your original article.  I
did test this and it does work. (ksh version 11/16/88d)  You might
want to put some error checking in the _cd function though.



-- 

|  	Eric H. Herrin II - {rutgers,uunet}!ukma!eric, eric@ms.uky.edu	     |

rob@mtdiablo.Concord.CA.US (Rob Bernardo) (04/12/91)

jeffo@uiuc.edu wrote:

>If I just had a way for ${PS1} to run a function without changing the value of
>${PS1}, I'd be set.

I don't think you can. PS1 is *evaluated* before use, but not "run".
-- 
Rob Bernardo					Mt. Diablo Software Solutions
email: rob@mtdiablo.Concord.CA.US		phone: (415) 827-4301