Printing styled text to the terminal - terminal

I have a program that I run through the command line and I wanted to print out bold or styled text similar to how the man pages are bold (I can't think of a styled example offhand).
How do I style text sent to the terminal?
If it makes a difference, I'm running a MacOSX terminal.

I believe you want to use the ncurses library to accomplish this.

You can have a look at this SO question: Colored grep? which shows a simple way to color output for VT100 terminals (works great on MacOSX)

Another useful SO Question is: Apply formatting to unix shell, with a link to ANSI escape codes, and examples from a shell.

You can do this from any shell script using the tput program to output terminfo codes. Oddly, there's a code to turn vold on but not off---you have to turn everything off. Reverse video can be turned on and off with tput smso and tput rmso.
Here's an example for bold (/bin/ksh):
print -n "This word is "; tput bold; print -n "bold"; tput sgr0; print "!"
In most programming languages it is easier to fork a process and call tput than it is to bother with the ncurses library (to which tput is a command-line interface).

Related

Highlighting or underlining output to stdout on Windows

Background
I need to port a Perl script from Linux to Windows. The script outputs to stdout and highlights and underlines specific words as needed. In Linux, this can be accomplished by surrounding the word(s) with system calls to tput:
tput smso and tput rmso for highlighting
tput smul and tput rmul for underlining
Question
Are there any system calls on Windows that can easily accomplish this functionality? If not, does anyone know a workaround that would accomplish similar results?
If you're using Perl to output stuff, at least Win32::Console can do underline on Windows (10 onwards) as well:
my $win32_console Win32::Console->new();
# Rendering is flakey under Windows 10
my $attr = 0x8000 # COMMON_LVB_UNDERSCORE, Windows 10 onwards
| 0x4000 # COMMON_LVB_REVERSE_VIDEO, Windows 10 onwards
;
$console->Attr($attr);
$console->Write("Hello World");
But if you're just looking for a Really Quick porting fix, Win32::Console::ANSI will "magically" convert all ANSI sequences in your output to the appropriate console calls.

Colorize B&W terminal-based apps?

Is there any software that will automagically add terminal colors to terminal-based apps that don't support colors?
How would it work? Well, the software could at least try to identify source code in the same way that syntax highlighters do (albeit most syntax highlighters would have problems with parts of the source tree being off-screen), and this general method can be extended to lots of other more-human forms of data; for example, dates, times, money, email addrs, etc are easy to automatically identify.
There are two parts to the question:
1) How do I add colors in general? Those are signaled via ANSI Color Codes
For example:
$ echo -e "plain \033[0;36mcyan\033[0;0m"
You should see plain cyan, with "cyan" colored.
2) How do I add colors to my specific app? For a standard command-line utility that writes to standard output, you can pipe it to a script that inserts the color codes:
$ echo "plain cyan" | sed 's/cyan/\\033[0;36mcyan\\033[0;0m/'
plain \033[0;36mcyan\033[0;0m
$ echo "plain cyan" | sed 's/cyan/\\\\033[0;36mcyan\\\\033[0;0m/' | while read x; do echo -e "$x"; done
plain cyan
Depends what you mean by a terminal based app. If it's just writing to stdout then in theory you could pipe it to a filter that does what you suggest: "parse the input and modify the output" e.g. if it sees a keyword wrap it in "color tags" as required by your terminal.
If it's using something like "curses" to address the terminal screen, I think this becomes close to impossible. It might be ok on a single terminal type, but I suspect it would be a major effort.

How to color character linux terminal

I would like your your help writing some code:
I would like Ubuntu 12.04.1 Terminal to color "/" character opposite as other text.
This could be very important for pretty much everyone, who writes bash/python directly in console...
Any ideas where to start?
I'm thinking of a custom plugin fo terminal, that could parse text right before it is printed?
The tput command is your friend (assuming you want to stay in shell-script land).
$ tput smso; echo Bold text; tput rmso
Q: What will highlighting / characters give you?

"CLS" Equivalent in BASH?

How do you clear the entire terminal in BASH, like the command prompt's cls command?
clear doesn't work because it doesn't actually clear anything, it just scrolls down.
As far as I know, there isn't a way to do this any better than what clear does with bash.
I think it's a feature that could be built into the terminal you're using though. I know the Mac Terminal app has a 'Clear Scrollback' menu option (command + k) that does what you're asking for.
Why don't you try Ctrl+l (control, lowercase "L"). This works in most shells (err terminals)...
In OSX terminal -
Command ⌘+l (command, l) leads to removing last typed command from display.
Command ⌘+k (command, k) leads to removing/clearing all display buffer.
reset (type this in terminal) leads to reset of terminal in case display becomes garbled.
not sure of equivalent in other unix flavors.
You're probably looking for the reset command.
However, the scroll-back buffer is not a feature of bash but of the terminal program. You didn't say what terminal program you were using.
xterm will allow the escape sequence ESC [3J to clear the scroll back, so you could do:
alias cls="clear; printf '\033[3J'"
Short Answer
clear && clear
or
tput reset
Other Ways
Here are all the ways you can clear the terminal screen in Unix:
clear # only clear visible screen
clear && clear # clear buffer as well
tput clear # same as clear but by sending escape seq
reset # clear + reset internal terminal state + 1sec delay
tput reset # same as reset but without 1sec delay
stty sane # don't clear screen but reset some terminal options
echo -e "\033c" # same as tput reset but hardcoded escape seq
printf "\033c" # same as tput reset but hardcoded escape seq
setterm -reset # same as tput reset, setterm has friendlier commands
Long Answer
The clear command only clears the visible screen but not the buffer so you can do Shift+PageUp to scroll up in the terminal and still view previous outputs. If you want to get same result as cls then do clear twice like clear && clear.
Another related command is reset which (I believe) resets the internal state of the terminal program. Unfortunately, this command includes 1 second of delay to support really old terminals. So if you are not ok with that kind of delay then use tput reset which seems to do same thing as reset minus the delay.
But what does tput do? In Unix, you can send terminal all kinds of ASCII character sequences which are interpreted as commands by the terminal. This allows you to do funky things like blink or color the text or turn off echo (during password typing) or set terminal options or do clear or reset. This you can send by tput clear or tput reset. The clear and reset command are equivalent but they run from the binaries that comes with your distro and may do additional stuff. The setterm -reset is similar to tput reset. Setting terminal using setterm is usually better because unlike tput it has more readable options in general case however we here use tput because it's smaller in length :).
You might have also seen people using things like echo -e "\033c" or printf "\033c" which is equivalent to tput reset but the escape sequence is now hard coded. The tput looks up terminal properties and uses the right escape sequence.
Another related command is stty sane which actually doesn't do any screen clearing but it sets many of the terminal options to defaults so if your terminal looks garbled or if terminal stays blank when you type (for example, because you printed binary file to terminal with escape sequence to turn off echo) then this command might help. For extreme garbled terminal cases, you can use all of the available resetting techniques in the sequence. I've alias like this for such occasions:
alias cls='tput reset'
alias clshard='reset; stty sane; tput rs1; setterm -reset; tput reset'
Related
What's the equivalent of the “cls” command from Windows/DOS?
What commands can I use to reset and clear my terminal?
Use ⌘+K. It removes the entries so I can't scroll up anymore.
So ⌘+K to clear everything including scrolling.
Ctrl+L to clear terminal window but still be able to see everything when scrolling up.
In ~/.bashrc, the perfect cls is:
cls () {
printf -- '%b' '\033c'
return $?
}
The clear command works for me.
But I personally find it impractical, because, for me, it clears the scrollback permanently and irreversibly. However, often I want just to insert some "marker"/"separator" into the scrollback, in order to be able to visually distinguish the "recent scrollback" from the "too old scrollback" (but sometimes ability to see the "too old scrollback" would be still useful). So I use something like:
yes '' | head -n100
That inserts 100 empty lines into the scrollback. (Inspired by this answer. You can vary the number of lines, of course.)

Shell Prompt Line Wrapping Issue

I've done something to break my Bash Shell Prompt in OS X (10.5.7) Terminal.
This is the PS1 that I had configured:
PS1='\[\e[1;32m\]\h\[\e[0m\]:\[\e[1;34m\]\w\[\e[0m\]\$ '
As far as I can tell I have the color commands escaping correctly. However when I scroll up and down in my command history I often get line wrapping issues if the historic commands wrap onto multiple lines.
I simplified my prompts to the following:
PS1='\[\e[1m\]\h:\w\$ \[\e[0m\]'
PS2='> '
And I still see something like:
localhost:~/Library/Application Support/Firefox/Profiles/knpmxpup.Defau
lt/extensions/{1A2D0EC4-75F5-4c91-89C4-3656F6E44B68}$ expocd \{1A2D0EC4-7
5F5-4c91-89C4-3656F6E export PS1="\[
\e[1;32m\]\h\[\e[0m\]: cd Library/Appl
ication\ Support/
I've also tried \033 instead of \e. I just included PS2 up there for information, I haven't changed that from the install default. If I completely remove the color codes then everything works fine, any ideas?
I am now using this PS1 with good effect:
green=$(tput setaf 2)
blue=$(tput setaf 4)
bold=$(tput bold)
reset=$(tput sgr0)
PS1="\[$green$bold\]\h\[$reset\]:\[$blue$bold\]\w\[$reset\]\$ "
Scrolling through my command history appears to handle line wraps now. However in the meantime since this question was asked I have also updated my OS X to 10.6.3
This stackoverflow thread seems relevant. As someone noted in that thread, the Bash FAQ at mywiki.wooledge.org discusses how to properly quote color codes in Bash prompts (FAQ 53), and the proper invocation of terminal colors (FAQ 37).
Line wrapping issues in Bash are nothing new. Your PS1 should work as is but there is a bug in Bash 3.2.49. Consult the mailing list, there's yet another bug regarding this which was confirmed to be fixed in 4.0.
You can't do much more than tagging unprintable characters with \[ and \], the rest must be done by the prompting code.
It seems that you have correctly escaped and enclosed sequences.
A workaround I use anyway it it to add a '\n' at the end. I find it clearer and lessen any problem with wrapping issues. The exact end of my PS1 is :
'\n\[\033[0;30m\]$\[\033[0m\]
An excellent howto you probably know :
Bash prompt howto
I noticed that there are some issues with the prompt cursor positioning even if there are no special character in the PS1 or PROMPT environment variable.
If we output a file that does not have a end-of-line char at the end. It will confuse the prompt.
You can reproduce this by doing:
curl https://gist.githubusercontent.com/martinos/d4aa0a7d4d752b0d0d9f/raw/3198c39f84a080c44227a084a19fb3a0bb661ee5/wrapping_issue.txt
and pressing the up key multiple times and you will see that the prompt get confused.
You can see an example of this in action:
https://asciinema.org/a/9mtjhi9dib6md4ocsbw210cca
When this occurs, just press <CTRL-C> and the prompt will come back to normal.
Note that ZShell does not have this issue.
For future reference, this is what I use:
export PS1="\[\033[0;31m\][\u#Project:\w]$\[\033[0m\] "
This would display my shell prompt as:
[ec2-user#Project:~]$
Helps me distinguish between live and dev sites.
Here's mine: it's the best one I've found, but the site where I originally found it was missing an escape character, leading to the line wrapping issue. I tinkered with it and finally got it working. It shows your user, path, and branch info with good contrast, color-wise.
export PS1='\[\e[1;37m\]\[\e[1;32m\]\u\[\e[0;39m\]:\[\e[1;33m\]\w\[\e[0;39m\]\[\e[1;35m\]$(__git_ps1 " (%s)")\[\e[0;39m\] \[\e[1;37m\]|\[\e[0;39m\]\$'
Also, add
GIT_PS1_SHOWDIRTYSTATE=true
To show a marker when a branch is "dirty" (changes to be committed exist)
export HISTCONTROL=ignoredups
Is also useful to ignore duplicates when scrolling up through bash history.
bind "set completion-ignore-case on"
Helps too.
Lastly,
shopt -s checkwinsize
May be helpful on OSX if issues persist.
'shopt -s checkwinsize' also works for Cygwin wrap problems also
If you're using the title bar trick "\e]2;titlebar\a", make sure to escape that too: "\[\e]2;titlebar\a\]"

Resources