Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Is there a way to hide some information in the Bash prompt ($PS1), e.g. something like an "invisible color", using ANSI escape sequences.

The method should be universal. It should not use a special invisibility feature of some rare terminal types. The hidden data should remain hidden in e.g. a pure Linux console ($TERM == linux) as well.

share|improve this question
    
what would be the purpose of this? –  akira Jul 12 '10 at 12:42
    
@akira the purpose is to include some additional meta information (which will be then get by a logging/parsing system using ttyrpld) –  mykhal Jul 12 '10 at 13:33
    
For some ideas for logging, see my answer here. –  Dennis Williamson Jul 12 '10 at 14:05

1 Answer 1

Set the foreground and background colors the same:

PS1='\[$(tput setab 0)$(tput setaf 0)\]hello\[$(tput sgr0)\]$ '

If your screen background color is different then you'll get a colored bar which will show, but the text will still be invisible. If you're using a mouse, you'll be able to select, copy and paste it and the pasted copy will be visible.

By using tput instead of hard-coding the escape codes, this will be portable to different terminal types. You can speed things up, though, if you define variables at the same time you define PS1 and use them in your prompt. That way, tput isn't called multiple times every time a prompt is issued.

back=$(tput setab 0)
fore=$(tput setaf 0)
none=$(tput sgr0)
PS1='\[$back$fore\]hello\[$none\]$ '

Edit:

To make apparent zero-width text included in the prompt, just backspace over it. To get the ^? just press Ctrl-v then backspace.

PS1='\[hello ^?^?^?^?^?^?\]$ '

To accommodate text of various widths:

PS1='This shows\[$(word='This doesn't';bs=${word//?/^?};echo "$word$bs")\]$ '

Using a variable would probably defeat your purpose of parsing for meta-data, but I include it for completeness:

text='Something to hide'
PS1='This shows\[$(word=$text;bs=${word//?/^?};echo "$word$bs")\]$ '

or

PS1='This shows\[$(bs=${text//?/^?};echo "$text$bs")\]$ '

Edit 2:

For that matter, you could do this:

PS1='This shows$(: This is hidden)$ '

Edit 3:

To make it more dynamic, use PROMPT_COMMAND to set PS1:

$ PROMPT_COMMAND="PS1='This shows\$(: '\$data')$ '"
This shows$ data="This is hidden"
This shows$ echo "Prompt: $PS1"
Prompt: This shows$(: This is hidden)$ 
This shows$ data="Top Secret"
This shows$ echo "Prompt: $PS1"
Prompt: This shows$(: Top Secret)$ 

Quoting can be a challenge. If you can avoid having single or double quotes in your data, the PROMPT_COMMAND technique will work OK.

share|improve this answer
    
by invisible, i meant rather entirely invisible, i.e. zero width. but that tput is helpul, thanks –  mykhal Jul 12 '10 at 13:42
    
@mykhal: see my edit. –  Dennis Williamson Jul 12 '10 at 13:49
    
@mykhal: See edit 2! –  Dennis Williamson Jul 12 '10 at 14:11
    
@[Dennis Williamson] interesting ideas! however, $(: TEXT)$ syntax from edit 2 is not usable for this purpose, since the text is hidden completely :) i still hope there exist some less hackish solution –  mykhal Jul 12 '10 at 15:02
    
@mykhal: I'm sorry, the apostrophe is the problem with that example. Try it without. What would you imagine might be less "hackish"? –  Dennis Williamson Jul 12 '10 at 15:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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