0

I'm trying to create an interactive bash script, where i can call given options from 1-n or just them like commands.

It will end up with a simulated prompt and 'read' is used to get the input, ofc.

But, if i type too big of a text, it will return to the beginning of the line and overwriting the prompt as i type.

Prompt is color coded and if i remove color escapes it will be just fine. But i like colors :)

Script prompt is like this:

NOC=$(echo -en '\033[0m')               # Default
RED=$(echo -en '\033[00;31m')
YELLOW=$(echo -en '\033[00;33m')
CYAN=$(echo -en '\033[00;36m')

OPROMPT="${RED}[Admin${CYAN}@${RED}bulletproof]#${NOC}"

until [ ! -z "$MCHOICE" ]; do
        read -p "${OPROMPT} " -e MCHOICE
done

What am i supposed to do to stop this behavior ? Cant seem to figure it out. If i use echo or printf to display the prompt, it will erase it if i type something and then hit backspace to correct it.

If I'm not clear, here's an example: This is the prompt (just picture it colored :P)

"[Admin@bulletproof]# "

...now here comes typing commands:

"[Admin@bulletproof]# vpn start my"

... now i continue typing

"domain.lanletproof]# vpn start my"

When it should be:

"[Admin@bulletproof]# vpn start mydomain.lan"

I also noticed that the buffer is different depending on the terminal window size. It doesn't start cutting off at same point when i have the terminal maximized, but has longer "tolerance"

EDIT: Just figured a way to substantially improve 'buffer' about this one.

If i set the code like this:

until [ ! -z "$MCHOICE" ]; do
        printf "$OPROMPT"
        read -p " " -e MCHOICE
done

It will allow me to input a lot longer text... Don't know why..

  • All those color-changing escape sequences need to be enclosed with \[ and \] so that bash knows they don't occupy any space on the screen. – Mark Plotnick Dec 8 '18 at 15:59
  • I don't get it? How do i enclose them? I just tried NOC=$(echo -en '[\033[0m]') # Default RED=$(echo -en '[\033[00;31m]') YELLOW=$(echo -en '[\033[00;33m]') CYAN=$(echo -en '[\033[00;36m]') But still doesn't work. Or i should've tried something else? I'm not talking about PS1 here, just trying to impersonate it – Marko Todoric Dec 8 '18 at 16:05
  • Still not doing it unfortunately. I've set NOC=$'\[\e[0m\]' RED=$'\[\e[00;31m\]' YELLOW=$'\[\e[00;33m\]' CYAN=$'\[\e[00;36m\]' OPROMPT="${RED}[Admin${CYAN}@${RED}bulletproof]#${NOC}" read -p "$OPROMPT " -e MCHOICE Bash version is 4.4.23 on Fedora 29. – Marko Todoric Dec 10 '18 at 8:32
  • The problem is the coloring. I think that Mark and Marco gave the right hints. Just try them. – EnzoR Dec 10 '18 at 9:53
  • Sorry, I couldn't try this in a terminal window until this morning. I told you the wrong characters to use. Need to use \001 and \002 to surround the escape sequences in the read prompt. I've written up an answer. – Mark Plotnick Dec 10 '18 at 20:07
0

When reading from a terminal, bash uses the readline library when executing the read builtin. It also uses readline when inputting command lines. In order to handle line wrapping correctly, readline needs to know if any characters in the prompt string do not take up any space on the screen.

If you were to call readline from C, you'd surround any escape sequence used to change screen colors with Ctrl+A (\001) and Ctrl+B (\002).

Bash allows you to use \[ and \] instead of those control characters when assigning to the command prompt variables (PS1, PS2, etc.). More recent versions of gdb support this, too.

Apparently bash doesn't allow this convenience for read -p. So you'll need to use those control characters.

NOC=$'\001\e[0m\002'               # Default
RED=$'\001\e[00;31m\002'
YELLOW=$'\001\e[00;33m\002'
CYAN=$'\001\e[00;36m\002'

OPROMPT="${RED}[Admin${CYAN}@${RED}bulletproof]#${NOC}"

until [ ! -z "$MCHOICE" ]; do
        read -p "${OPROMPT} " -e MCHOICE
done

Tested with bash 4.4.23.

  • Well, gotta say : hats off to you, sir ! :) worked like a charm, now even prompt stays displayed when i resize the terminal, before it would disappear every time i resize it !! :) – Marko Todoric Dec 11 '18 at 23:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.