Walker Rowe
Walker Rowe

Reputation: 983

Prompt Mangled After Some Commands (f/e curl elasticsearch)

I've followed the instructions in the solutions https://unix.stackexchange.com/questions/105958/terminal-prompt-not-wrapping-correctly on how to set PS1. But my issue has nothing to do with the command being so long that is wraps around the screen. Instead it appears to be the result coming back from a previous command mangling the commands on the command line.

I am using the default .bashrc when you start up an Amazon EC2 Ubuntu 16.04 instance.

This series of steps will result in the command line being mangled:

First run this:

curl -X GET http://parisx:9200/_cat/indices

then this:

curl -X DELETE http://parisx:9200/.monitoring-es-6-2019.02.16

then it says this, notice already it says "ubu", showing that the command coming back has messed up the display already.

on the end.

{"acknowledged":true}ubu

Then scroll up and the next command is mangled:

GET http://parisx:9200/_cat/indicesoring-es-6-2019.02.16

but it still works, meaning it only appears mangled but actually is the correct command as when you run it and then check this history it shows this. So only what is displayed does not reflect what is to be run.

curl -X GET http://parisx:9200/_cat/indices

Here is PS1:

echo $PS1
\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$

Upvotes: 1

Views: 199

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295845

Explanation

It's ElasticSearch that's doing something wrong, by emitting a document without a trailing newline on the end: UNIX text files use newlines as line terminators, not line delimitors (as they're used on Windows).

Bash assumes that programs it invokes are well-behaved, and leave the cursor at the leftmost column; your output from curl is breaking that expectation.


Solutions


Overwriting non-newline-terminated output with the prompt

One approach is to modify your PS1 to explicitly add a carriage return to the front, so the prompt will always be printed from the front, overwriting any output from your prior command that wasn't newline-terminated:

PS1=$'\\[\r\\]'"$PS1"

Putting a newline before your prompt, preserving such output

Another is to add a newline at the front of your prompt, placing an extra line of whitespace after well-behaved commands and putting the prompt on the line immediately following the output of poorly-behaved commands:

PS1=$'\\[\n\\]'"$PS1"

Capturing and repairing output from badly-behaved programs

Another is to capture curl's output and re-emit it with a newline added when not already present. That might look like:

printf '%s\n' "$(curl -X GET http://parisx:9200/_cat/indices)"
printf '%s\n' "$(curl -X DELETE http://parisx:9200/.monitoring-es-6-2019.02.16)"

...which doesn't add extra newlines when one already existed on account of $(...) trimming any trailing newline during the capture.


Just Add An echo

Knowing the specific faulty commands, of course, you can just add trailing echos only for them:

curl -X GET http://parisx:9200/_cat/indices; echo
curl -X DELETE http://parisx:9200/.monitoring-es-6-2019.02.16; echo

...will solve the same issue with less overhead and fewer side effects.

Upvotes: 1

Related Questions