less -R versus less -r for preserving ANSI color in piped output
0 reputation · 29 Nov 2020, 02:14 UTC
0 reputation · 29 Nov 2020, 02:14 UTC
I want to view colorized command output through less while keeping ANSI formatting intact and avoiding terminal corruption from unexpected control characters.
less -R passes through only valid ANSI SGR escape sequences, while less -r sends all raw control characters to the terminal. The default strips non-printable characters and loses color. In less 551 and later, both behaviors are documented, but it is unclear which option is safer when a pipeline mixes SGR codes with OSC sequences, private modes, or occasional binary bytes.
Which flag should be the default LESS setting for colorized piped output? Under what input conditions does the risk of terminal state change outweigh the benefit of full raw pass-through?
For the vast majority of users and environments, -R should be the default setting for the LESS environment variable. It provides the necessary balance between preserving color and protecting the terminal emulator from corruption.
The core difference lies in how less handles non-printable control characters before passing them to your terminal:
-R (Raw Control Characters): Only passes through valid ANSI SGR (Select Graphic Rendition) escape sequences. It strips other control characters, such as those used for changing window titles or triggering system bells.-r (Raw): Passes every single byte from the input directly to the terminal. This includes SGR codes, OSC (Operating System Command) sequences, private modes, and arbitrary binary data.The risk of terminal state change outweighs the benefit of raw pass-through whenever the input source is untrusted or complex. Using -r can lead to several issues if the piped output contains non-SGR sequences:
less exits.less -r, the terminal may interpret random bytes as control codes, potentially changing the keyboard mapping or character set.| Feature | less -R |
less -r |
|---|---|---|
| ANSI Colors (SGR) | Preserved | Preserved |
| Window Titles (OSC) | Stripped | Preserved |
| Binary/Control Bytes | Stripped | Preserved |
| Terminal Safety | High | Low |
To set -R as your default, add the following to your shell profile (e.g., .bashrc or .zshrc):
export LESS='-R'
To verify the behavior, you can test how each flag handles a mix of SGR (color) and OSC (title) sequences:
# Create a test string with Green text and a Title change request
printf "\e[32mGreen Text\e[0m \e]0;New Title\a"
# Test -R: Should show green text, but NOT change terminal title
printf "\e[32mGreen Text\e[0m \e]0;New Title\a" | less -R
# Test -r: Should show green text AND change terminal title
printf "\e[32mGreen Text\e[0m \e]0;New Title\a" | less -r
Diagnostic Note: Does your specific workflow require the preservation of terminal window titles or custom Xterm private modes? If so, -r is necessary, but should be used as a one-off flag rather than a global environment setting.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 29 Nov 2020, 10:18 UTC
Setting LESS=-R protects the terminal, but it cannot restore color that the upstream command already removed. Many utilities disable ANSI SGR output when they detect a pipe instead of a TTY, so less -R receives plain text and displays nothing colored.
Force color at the source before piping:
grep --color=always "pattern" file | less -Rls --color=always | less -RCLICOLOR_FORCE=1 some-command | less -RThis assumes less 551 or later. -R still strips OSC sequences such as window-title changes, so those are intentionally lost even if the source emits them. Verify with printf '\e[31mred\e[0m\n' | less -R.