Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

user input in a shell script 3

Status
Not open for further replies.

LunaPan

Programmer
Jan 13, 2004
25
US
Hi, I need to get some user input using a shell script in unix. The trick is that after the prompt for the input, the old value needs to appear so the user can edit it and then submit. What I want is below:

Please update the following path:
/foo/bar/

Thanks!
 
I don't know of a way to do this, but a workaround might be to echo the path to the user before the read so that they know what to type before their input. Alternatively, if the path is static anyway, add it to the user input following the read. I'll be interested to see if anyone else can fulfill exactly what you want, as it would be useful for me too. Regards.
 
I am unclear of what you exactly want. Can you try to explain it differently?
 
Okay. Now that I reread it, are you wanting it to prompt:
Please update the following path:

and below that it would display the path:
/foo/bar/

??

Which means that you really don't want to use 'read' because you want to edit (/foo/bar/) and then enter that to be used for the rest of the script?
 
echo "this is what you need\b\b\b\b\b"

if the terminal does not support this, you need to look in termcaps to see what the non-desctructive backspace is.
 
knowitall: Yes, 'read' alone is not sufficient.

cdlvj: I think this is exactly what I need but I'm not sure how termcaps works, what exactly am I looking for?
 
There will be some kind of codes which are defined for the terminal like this is a highlight "^[[7m" for a wyse.

A HOME sequence will probable suit your needs.
 
Best I can come up with as of now. The user will have to press the "=" key and it will fill in /foo/bar/ and they can edit it.

Code:
#!/usr/dt/bin/dtksh

function vi_tab
{
    if [[ ${.sh.edmode} != "  " && ${.sh.edchar} == "=" ]] then
        .sh.edchar="/foo/bar/"
    fi
}

print "Prompt: \c"
trap 'vi_tab' KEYBD
read
 
that is brilliant...

relies on dtksh I guess, but good nevertheless

Mike

"Deliver me from that bane of civilised life; teddy bear envy."

Want to get great answers to your Tek-Tips questions? Have a look at faq219-2884

 
knowitall: Your dtksh code isn't working for me, I'm not sure that I have the KEYBD signal to work with here is a kill -l ...
Code:
kill -l
HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM USR1 USR2 CLD PWR WINCH URG POLL STOP TSTP CONT TTIN TTOU VTALRM PROF XCPU XFSZ WAITING LWP FREEZE THAW CANCEL LOST RTMIN RTMIN+1 RTMIN+2 RTMIN+3 RTMAX-3 RTMAX-2 RTMAX-1 RTMAX

cdlvj:
I'm still not exactly sure how to use the termcap codes. Say I wanted to use the "up" code, I tried doing this:
Code:
echo "Prompt: \E[A"
but all I got was: Prompt: \E[A

What am I doing wrong??? Here is the entry for xterm, the terminal I am using:

Code:
x1|xterm|vs100|xterm terminal emulator (X Window System):\
        :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:UP=\E[%dA:\
        :al=\E[L:am:\
        :bs:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:co#80:\
        :cs=\E[%i%d;%dr:ct=\E[3k:\
        :dc=\E[P:dl=\E[M:\
        :im=\E[4h:ei=\E[4l:mi:\
        :ho=\E[H:\
        :is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l:\
        :rs=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l\E<:\
        :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:kb=^H:kd=\EOB:ke=\E[?1l\E>:\
        :kl=\EOD:km:kn#4:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:\
        :li#65:md=\E[1m:me=\E[m:mr=\E[7m:ms:nd=\E[C:pt:\
        :sc=\E7:rc=\E8:sf=\n:so=\E[7m:se=\E[m:sr=\EM:\
        :te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:\
        :up=\E[A:us=\E[4m:ue=\E[m:xn:

Thanks for your help guys.
 
Bash read has a -e option that tells it to use Readline (the command line editing library used by Bash) to read the input. I can't find a way to make it put any default text there, though.

I'm not at a *nix machine right now, so I can't test this, but GNU Readline comes with an example program called rl that does what Bash's "read -e" does, but it has an option -d for default.

So perhaps:
Code:
rl -p "Please update the following path:" -d "/foo/bar/"
 
OK, figured it out, here's how I did it using dtksh:
Code:
		function vi_tab
		{
			if [[ "${.sh.edmode}" != "" && "${.sh.edchar}" == "=" ]] then
				.sh.edchar=`echo "$LETVALUE" | sed 's/[ \t]*$//'`
			fi
		}
		print "Enter a new path for this filename statement, press '=' to edit the old path:"
		set -o vi
		trap 'vi_tab' KEYBD
		read NEWVALUE

Thanks for both of your responses!


 
up="E[2A:"

echo "go up two lines ${up}" is how my script does it.
 
Well, it seems knowitall's solution is limited afterall. You can only substitute up to 80 characters this way, and thats too few for my paths :( I thought this might have something to do with the default value of COLUMNS being 80, but when I changed it to 200, I still only got 80 characters back, any ideas?
 
> any ideas?

Did
Code:
result=$(rl -p "Please update the following path:" -d "/foo/bar/")
not work?

It certainly seems like a cleaner, more portable way of doing things than trying to hack terminal escape sequences on your own, and Readline definitely works for more than 80 characters.


If you must play around with the terminal escape sequences, why not use tput instead?
 
Chipper: Although rl sounds great, I'm not sure how to go about installing a new command on an enterprise-wide system, I'm just a programmer recently getting into Unix scripting :)

tput does work much better thanks, but moving the cursor to the end of the path I want to edit does not let me edit the path, only enter new characters from that point.

 
> I'm not sure how to go about installing a new command on an enterprise-wide system.

I'm assuming you don't have superuser access to the machine, and that rl does not already exist on it. I'm also assuming that there won't be any problems with the script using a program that lives in your home directory

First, get it, upack it, and build it:
Code:
wget [URL unfurl="true"]http://mirrors.sunsite.dk/gnu/readline/readline-5.0.tar.gz[/URL]
tar xzf readline-5.0.tar.gz
cd readline-5.0
./configure
make


Now, you have to make rl, which is an example program (not an "official" program installed with the package).

If your system already has Readline installed:
Code:
cd examples
make rl

If it doesn't have Readline installed:
Code:
cd examples
gcc -g -o rl rl.o ../libreadline.a -ltermcap


Now, put it somewhere...:
Code:
cp rl ~/bin
...in your path
Code:
export PATH=$PATH:$HOME/bin


rl (but not Readline itself) is now installed for your personal use.



By the way, I tested it; it worked fine for me and does exactly what you want, as far as I can tell.
 
Actually, if your system already has Readline installed, you can probably skip the "./configure; make" part and go right to building rl.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top