1

I am writing a client for doing various tasks on the zimbra server via ssh, and I've hit a bit of a snag. Here's the code:

#!/bin/bash
set -e
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
export HISTCONTROL=ignoreboth

# History management
if [ -f $HOME/.zmcli_history ]; then
  history -r $HOME/.zmcli_history
else
  touch $HOME/.zmcli_history
  history -r $HOME/.zmcli_history
fi
trap "history -a $HOME/.zmcli_history && echo -e '\nExiting now.\n'" exit

# Styling
yellow='[33m'
bold='[1m'
off='[0m'

echo

# Client
while :; do
  read -ep "$bold${yellow}zimbra_cli[${off}server_domain$bold${yellow}]> $off" comm
  history -s "$comm"
done

NOTE: if you execute this script, it will create the history file (.zmcli_history) in your home directory.

Everything works as intended, and the history is all there, but often the part of some (usually long) previous command remains as I continue to scroll through history. That part of command acts as a part of the prompt for the rest of the session, unless I hit CTRL+L which clears the screen and resets it to normal. I have read through many posts that helped people who had this problem in their bash terminal. Their problem was that PS1 was improperly formatted and bash got confused about the length of the prompt string. It is probably something similar here, but those solutions do not work, because read command can not use those escape characters like echo can (\e).

I managed to find a way to escape the color sequences using literal escapes (CTRL+V ESCAPE in vim insert mode). So the colors work, but I am stuck with this history problem.

Things I have tried:

  • command substitution :: write and escape the color codes in a way that echo -e can print them, and then echo it in the read command $(echo -e '\e[33m'). Still seeing the colors, but didn't help with history problem
  • adding escaped [ and ] around the color codes
  • putting the whole prompt with color codes in a separate echo command that comes before the read command. The downside is that I can not turn off formatting until after the read command (in another echo), which means that the whole prompt and command will be bold and in color. Also, if I press CTRL+L now, even the prompt will get cleared, and I will only be left with the cursor

Finally, since I can not drop the history, I tried dropping the colors. But then it gets impossible to quickly differentiate between commands and output.

You can replicate the problem by starting the script and putting in 10-15 long (gibberish) commands. After that, try scrolling up and down through history and you will see what I'm talking about.

Anyone knows a way to make this work?

1 Answer 1

1

Your script, as it is, didn't allow me to replicate the problem. Only after enabling colors and such readline started getting confused. For the record, I enabled these things with

# Styling
yellow=$'\e[33m'
bold=$'\e[1m'
off=$'\e[0m'

And it's true \[ and \] don't help like they do in case of PS1.

But then I found this answer. It reads

I open info readline and found:

[…]
Applications may indicate that the prompt contains characters that take up no physical screen space when displayed by bracketing a sequence of such characters with the special markers RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE (declared in readline.h. This may be used to embed terminal-specific escape sequences in prompts.

As say text I search for RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE definition in readline.h and found next:

/* Definitions available for use by readline clients. */
#define RL_PROMPT_START_IGNORE  '\001'
#define RL_PROMPT_END_IGNORE    '\002'

This led me to the following:

# Styling
yellow=$'\1\e[33m\2'
bold=$'\1\e[1m\2'
off=$'\1\e[0m\2'

It works flawlessly.

2
  • Thank you very much, this solution works like a charm. I really explored this problem, but never stumbled upon anything like this.
    – gtxcpr
    Commented Mar 29, 2019 at 10:41
  • Btw, there were literal escapes before square brackets in the Styling section, but it looks like they can not be printed on this page, and I didn't notice when I posted the code. In vim they look like this ^[. Thx again
    – gtxcpr
    Commented Mar 29, 2019 at 10:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .