Is it possible to make stdout and stderr output be of different colors in XTerm or Konsole?
Here's a solution that combines some of the good ideas already presented.
Create a function in a bash script:
color() ( set -o pipefail; "$@" 2>&1>&3 | sed $'s,.*,\e[31m&\e[m,' >&2 ) 3>&1
Use it like this:
$ color command -program -args
It will show the command's stderr
in red.
Keep reading for an explanation of how it works. There are some interesting features demonstrated by this command.
color()...
— Creates a bash function called color.set -o pipefail
— This is a shell option that preserves the error return code of a command whose output is piped into another command. This is done in a subshell, which is created by the parentheses, so as not to change the pipefail option in the outer shell."$@"
— Executes the arguments to the function as a new command."$@"
is equivalent to"$1" "$2" ...
2>&1
— Redirects thestderr
of the command tostdout
so that it becomessed
'sstdin
.>&3
— Shorthand for1>&3
, this redirectsstdout
to a new temporary file descriptor3
.3
gets routed back intostdout
later.sed ...
— Because of the redirects above,sed
'sstdin
is thestderr
of the executed command. Its function is to surround each line with color codes.$'...'
A bash construct that causes it to understand backslash-escaped characters.*
— Matches the entire line.\e[31m
— The ANSI escape sequence that causes the following characters to be red&
— Thesed
replace character that expands to the entire matched string (the entire line in this case).\e[m
— The ANSI escape sequence that resets the color.>&2
— Shorthand for1>&2
, this redirectssed
'sstdout
tostderr
.3>&1
— Redirects the temporary file descriptor3
back intostdout
.
Here's an extension of the same concept that also makes STDOUT green:
function stdred() (
set -o pipefail;
(
"$@" 2>&1>&3 |
sed $'s,.*,\e[31m&\e[m,' >&2
) 3>&1 |
sed $'s,.*,\e[32m&\e[m,'
)
Bash, how to visually distinguish stdout from stderr?
Well, a few options.
Easiest would be to use hilite.
Other options would include writing custom shell wrapper to colorize the input.
A few options are here (note, that they are pretty much xterm-specific).
Using colors with printf
You're mixing the parts together instead of separating them cleanly.
printf '\e[1;34m%-6s\e[m' "This is text"
Basically, put the fixed stuff in the format and the variable stuff in the parameters.
In linux, how can I test whether the output of a program is going to a live terminal or to a file?
isatty(int fd)
will check whether the fd refers to a terminal or something else. It's part of unistd.h
in the GNU C library.
Man page: http://linux.die.net/man/3/isatty
As an aside: if you want to read from a program using another program, but you want to fool isatty
into thinking that your program is a human, there is a way to do that. You can use a pseudo-terminal (pty). This technique is used by expect, for example.
How do I output coloured text to a Linux terminal?
You need to output ANSI colour codes. Note that not all terminals support this; if colour sequences are not supported, garbage will show up.
Example:
cout << "\033[1;31mbold red text\033[0m\n";
Here, \033
is the ESC character, ASCII 27. It is followed by [
, then zero or more numbers separated by ;
, and finally the letter m
. The numbers describe the colour and format to switch to from that point onwards.
The codes for foreground and background colours are:
foreground background
black 30 40
red 31 41
green 32 42
yellow 33 43
blue 34 44
magenta 35 45
cyan 36 46
white 37 47
Additionally, you can use these:
reset 0 (everything back to normal)
bold/bright 1 (often a brighter shade of the same colour)
underline 4
inverse 7 (swap foreground and background colours)
bold/bright off 21
underline off 24
inverse off 27
See the table on Wikipedia for other, less widely supported codes.
To determine whether your terminal supports colour sequences, read the value of the TERM
environment variable. It should specify the particular terminal type used (e.g. vt100
, gnome-terminal
, xterm
, screen
, ...). Then look that up in the terminfo database; check the colors
capability.
How to overwrite stdout in C
It's not manipulating stdout -- it's overwriting the characters which have already been displayed by the terminal.
Try this:
#include <stdio.h>
#include <unistd.h>
static char bar[] = "======================================="
"======================================>";
int main() {
int i;
for (i = 77; i >= 0; i--) {
printf("[%s]\r", &bar[i]);
fflush(stdout);
sleep(1);
}
printf("\n");
return 0;
}
That's pretty close to wget
's output, right? \r
is a carriage-return, which the terminal interprets as "move the cursor back to the start of the current line".
Your shell, if it's bash
, uses the GNU Readline library, which provides much more general functionality, including detecting terminal types, history management, programmable key bindings, etc.
One more thing -- when in doubt, the source for your wget, your shell, etc. are all available.
how to get current terminal color pair in bash
The question was about the current color, not the cursor position.
Both are "nonstandard" (though the latter, cursor position report is implemented by anything which has a valid claim to "VT100 emulator").
However, xterm implements a set of escape sequences referred to as dynamic colors, which predate the ANSI color functionality. Those set the working colors including text foreground and background. I modified this in 2002 to allow an application to send the sequence with a "?" rather than a color to tell xterm to return the color value, e.g.,
OSC 1 1 ? ST
using the notation given in XTerm Control Sequences
Curses can_change_color() always returns False
can_change_color() actually reports whether colors can be remapped, via init_color() -- an uncommon capability -- not whether colors can be used at all, via init_pair(). To check for that basic color capability, what you want is has_colors().
init_color(), on the terminals where it works, lets you do things like tweak the exact shade of blue used -- or make the terminal's idea of "blue" show up as something else entirely.
Related Topics
List Files Over a Specific Size in Current Directory and All Subdirectories
Sed Insert Line with Spaces to a Specific Line
Sanitize Environment with Command or Bash Script
How to Monitor Data on a Serial Port in Linux
Run a Shell Script in New Terminal from Current Terminal
Mongo: Couldn't Connect to Server 127.0.0.1:27017 at Src/Mongo/Shell/Mongo.Js:145
Lsb_Release: Command Not Found in Latest Ubuntu Docker Container
Linux Kernel Interrupt Handler Mutex Protection
Differencebetween Nptl and Posix Threads
I Want to Contribute to the Linux Kernel
X11/Xlib.H Not Found in Ubuntu
Importing a Cmake Project into Eclipse Cdt
Linux Distribution Binary Compatibility
How to Determine If Lcd Monitor Is Turned on from Linux Command Line
How to Write a Linux Daemon with .Net Core