53

I understand ls uses dircolors to display colored output. dircolors has default database of colors associated with file extensions, which can be printed wiht the command

dircolors --print-database

From man dir_colors I read, the system-wide database should be located in /etc/DIR_COLORS. But this file does not exist on my system (Debian). How can I modify system-wide color settings for dircolors? Where does the command dircolors --print-database take the settings from, when no file exists.

I am aware that user can have user-specific file ~/.dircolors with his settings, but this is not suitable for me, since I need to change the settings for everybody.

A second questions is, whether it is possible to use 8-bit colors for dircolors. My terminal is xterm-256color.

4 Answers 4

51

ls takes it color settings from the environment variable LS_COLORS. dircolors is merely a convenient way to generate this environment variable. To have this environment variable take effect system-wide, put it in your shell's startup file.

For bash, you'd put this in /etc/profile:

# `dircolors` prints out `LS_COLORS='...'; export LS_COLORS`, so eval'ing
# $(dircolors) effectively sets the LS_COLORS environment variable.

eval "$(dircolors /etc/DIR_COLORS)"

For zsh, you'd either put it in /etc/zshrc or arrange for zsh to read /etc/profile on startup. Your distribution might have zsh do that already. I just bring this up to point out that setting dircolors for truly everybody depends on the shell they use.

As for where dircolors gets its settings from, when you don't specify a file it just uses some builtin defaults.

You can use xterm's 256 color escape codes in your dircolors file, but be aware that they'll only work for xterm compatible terminals. They won't work on the Linux text console, for example.

The format for 256 color escape codes is 38;5;colorN for foreground colors and 48;5;colorN for background colors. So for example:

.mp3  38;5;160                   # Set fg color to color 160      
.flac 48;5;240                   # Set bg color to color 240
.ogg  38;5;160;48;5;240          # Set fg color 160 *and* bg color 240.
.wav  01;04;05;38;5;160;48;5;240 # Pure madness: make bold (01), underlined (04), blink (05), fg color 160, and bg color 240!
3
  • 1
    could you please explain how I can use the 256 color escape codes? Let's say I want to change the following .mp3 00;36 to use color126 from the xterm-256 colors chart upload.wikimedia.org/wikipedia/en/1/15/Xterm_256color_chart.svg Oct 9, 2013 at 18:26
  • 1
    Sure, see my edit.
    – Matt
    Oct 9, 2013 at 18:52
  • 1
    You make it seem like /etc/DIR_COLORS should exist. It might exist on Red Hat or derivatives. But I'm not sure. Not on my machine.
    – x-yuri
    Sep 1, 2022 at 8:45
10

Where does the command dircolors --print-database take the settings from, when no file exists.

As per the manual, it uses a precompiled database in the absence of a file.

If file is specified, dircolors reads it to determine which colors to use for which file types and extensions. Otherwise, a precompiled database is used. For details on the format of these files, run ‘dircolors --print-database’.

In order to change the settings for everybody, you could create a /etc/dircolors file and add the following to /etc/bashrc:

d=/etc/dircolors
test -r $d && eval "$(dircolors $d)"
9

Linux set console background colors with dircolors:

Your dircolors file controls the colors for words that appear through ls on the console. Find this .dircolors file for your distribution, a link to help:

http://www.linuxfromscratch.org/blfs/view/svn/postlfs/profile.html

For me on Fedora 17, my dircolors file is: /etc/DIR_COLORS

Copy /etc/DIR_COLORS into your /home/el/.dircolors directory. Create it if it doesn't exist.

Edit /home/el/.dircolors, look for the text "dir".

Change this:

DIR 01;34   # directory

To this:

DIR 01;36   # directory

Save and close and restart the shell. The directories go from dark blue on black (unreadable) to bright teal on black (readable).

1
  • 4
    -1: no /etc/DIR_COLORS in OP's distro, Debian. And he already knows about ~/.dircolors, that was not the question
    – MestreLion
    Jan 29, 2015 at 8:01
9

SHORT ANSWER

dircolors (short for Directory Colors) can't be used to modify colors globally. To do that, you probably want to be adjusting the color palette in your terminal emulator.

For instance, dircolors is not used to adjust the colors requested by grep, vi, tmux, or man.

dircolors is used to adjust the colors that the commands ls and tree request to be displayed when displaying your filenames.

I stress request to be displayed, because the colors a command requests are only what is sent to your terminal emulator. Your terminal emulator can then choose to display different colors than those requested. What are requested, and what are finally output to your terminal screen that you'll see, can be two different sets of colors.


OVERVIEW OF THE COLOR PROCESS

1) Any text based program or shell built-in, can by design, output ANSI (American National Standards Institute) color-request escape codes. Here I emphasize that these are only requests to the terminal, which has the final decision of how to display them. The ANSI color code system is a very old system, first originating on stand-alone hardware terminals.

A colored text request looks something like:

<requested-color><text-to-be-displayed-in-that-color><next-requested-color><next-text...

The 'requested-color' part is not displayed. Rather it is used by the terminal emulator to get the screen to show 'text-to-be-displayed-in-that-color' in the requested-color.

Programs can call [ncurses][1] to output ANSI codes to the terminal emulator. You basically have 8 standard colors, and 8 more bold/bright colors that can be requested. (ncurses is short for New Curses, where 'curses' is a pun on Cursor Optimization, or a software library for efficient text based output to a terminal screen.)

Many common text based commands can be configured to output ANSI color codes to request that their output be colorized by the terminal. Examples are: ls, tree, vim, grep, tmux, and man.

These output color codes (escape prefixed control codes) request that the display change to a given color combination (foreground, background, and attributes) before the next text is output. Again, these escape codes do not actually determine the colors that you see. Rather they specify particular palette choices.

In the past there was a standard palette of colors. If you requested green then you would see green.

But a terminal emulator, like GNOME Terminal for example, can change this behavior. For example, if a program requests green, via an ANSI green escape code, you can decide that this should instead be displayed in cherry-red on your screen. What's important to remember, is that this means that: all requested greens, in every terminal program, will be converted to red. In other words, you can't just adjust the output colors of one particular program, like grep this way.

2A) Directory commands like ls and tree are somewhat special, in that they can be user-configured to colorize filenames by filename-type to your specification. This is different than man, for example, which uses a fixed set of alternate colors in addition to black and white.

For example, folders might be requested to be shown in navy-blue, while links are requested to be shown in light-blue.

You can request color for specified terminal formats (like ansi or putty), and by file basic type (like folder, block, or sticky), and/or by matching filename extension (like *.sh, or *.png). This is done by changing the ANSI output color codes by file name type using settings given by the LS_COLORS environment variable. See below for how.

2B) There are also special color schemes in vim using for example :colorscheme default. (A subject for another day.)

3) Your terminal (GNOME Terminal in my case) then interprets any ANSI codes to generate the actual display colors that you see.


GLOBALLY ADJUSTING COLORS IN YOUR TERMINAL EMULATOR

If you adjust the color settings in GNOME Terminal (or probably any terminal emulator that support this feature) it will affect the observable colors of any and all text programs that output ANSI color codes. These color changes will be simultaneously adjusted on all open terminal windows (assuming you're using the same terminal emulator for all windows).

If you were using 2 different terminal emulators (like both GNOME Terminal and XTerm), then each could be adjusting the final output colors differently.

With the GNOME Terminal Preferences you can fine tune your system-wide 'color palette' (i.e. the set of 16 colors available to text based applications), to your own custom set of colors.

GNOME Terminal Help says:

Traditionally terminal emulators offered a 16 color palette, this is what you can alter here. Terminal supports an extended set of 256 colors, but the additional 240 colors cannot be edited here. Terminal even offers direct access to over 16 million colors, this is called “true color” mode.

If the changes you make to the palette do not seem to have an effect, presumably the contents you see consist of such extended palette colors or true colors, rather than the 16 base colors.


USING DIRCOLORS

Here's how that works:

a)  Run  $ dircolors -p >/etc/DIR_COLORS   # to produce DIR_COLORS template file

b)  Hand edit /etc/DIR_COLORS to adjust ANSI color codes that will be output
    for various things to display.  For example, any filenames like *.png can 
    request a particular ANSI color combination.  (ANSI color codes are escape
    prefixes.)

c)  Run dircolors again, this time in both 
       /etc/profile       (for logins)           and
       /etc/bash.bashrc   (for terminal windows)
    to read DIR_COLORS and create and export the LS_COLORS 
      environment variable, like this:

        $ eval "$(dircolors -b /etc/DIR_COLORS)"

I call dircolors early in my /etc/profile where I use it to set and export LC_COLORS.

# === Create DEFAULT LS_COLORS ENVIRONMENT VARIABLE ===========================
# /etc/DIR_COLORS is a data file from:  $ dircolors -p > /etc/DIR_COLORS
eval "$(dircolors -b /etc/DIR_COLORS)"      # This reads /etc/DIR_COLORS 
# and then runs these two commands:   
#
#   $ LS_COLORS=...     # <-- where this value is created from /etc/DIR_COLORS
#   $ export LS_COLORS

For reference, how I'm enabling colors in various commands in /etc/profile (which is read whenever a login is done, (including $ bash --login)) is below, at the very bottom of this answer.

Note that there are some reverse video folders and files that display funny with ls (e.g. DOS backup files). No amount of messing in GNOME Terminal (below) seems to affect these colors. But you can edit DIR_COLORS used by dircolors (see notes above) to adjust things with LS_COLORS.

enter image description here


TIPS FOR HOW TO ADJUST YOUR OWN SYSTEM'S COLORS

From the GNOME Terminal menu select Edit | Preferences. In the left had pane choose the profile you want to adjust, and in the right hand pane select the Colors tab.

!! BEFORE YOU PROCEED, I STRONGLY SUGGEST YOU MAKE A BACKUP OF YOUR EXISTING PREFERENCES. A screen-shot will do nicely. See screen shot of mine below.

TL;DR - If you don't want to set this checkbox: enter image description here

to use the most basic defaults, but instead you want a black working background with colored up bash, vim, grep, ls, ... apps, then try setting your colors like this:

enter image description here

I found this colors dialog to be a bit confusing at first, but it's logical once you figure it out. The biggest problem is that all my text apps share the same color palette, but they use it somewhat differently, especially ls.

Here are the exact colors I'm using:

black           aqua            green           orange          light yellow    purple          blue, primary   gray (X)        <-- X=Don't care
#000000         #01B9E0         #389400         #FF8A00         #F4FF92         #C401C4         #005EEA         #AAAAAA
0               1               2               3               4               5               6               7
------------    ------------    ------------    ------------    ------------    ------------    ------------    ------------    <-- 1st set are     "normal   colors"

------------    ------------    ------------    ------------    ------------    ------------    ------------    ------------    <-- 2nd set are the "brighter colors" (for check box below)
8               9               10              11              12              13              14              15
#555555         #FF5555         #55FF55         #FFFF55         #5397FE         #FF55FF         #55FFFF         #D6D6D6
dark gray (X)   red/orange      lime            yellow (X)      blue, medium    pink            aqua, bright    light gray (X)  <-- X=Don't care

UNDERSTANDING THE GNOME TERMINAL 'PREFERENCES - PROFILE' DIALOG

The top and bottom sections (Text and Background Color and Palette) seem to operate almost completely independently, except that the Palette selections are a layer on top of (i.e. further modify) the top settings in Text and Background Color. (Also even if Use colors from system theme is checked, Show bold text in bright colors at the bottom still matters, at least for ls.)


First let's mess with the Text and Background Color settings.

These determine default colors for basic, non-special Text and Background colors. You can also choose optional modifiers for Bold or Highlight text, and for a fixed cursor color if you want that, like bright orange for example might make some people happy.

The Use colors from system theme checkbox seems to decide if you want to inherit color settings or define them yourself. When you uncheck it, you can choose a a built in or custom scheme from the pull down.

What you choose gets stuffed into the Text and Background swatches below, except for Custom.

Note that your choices here don't effect the other 3 check boxes below it.

Also note that if you first click on the Text or Background swatch, you'll get a color chooser, and once you choose Select in it, it sets the Built-in schemes pull down to Custom.

If you check Bold color and set a color, then text that is specified as bold by a program, gets this color override.

If you check Cursor color, then you can choose fixed colors for your cursor. (Note, you will have to move the cursor over text to see it change.) Without this checked the cursor seems to vary with the color of text its over.

If you check Highlight color, you'll see the effect of these two swatches for example in vim when you drag the mouse to copy some text.


Now it's time to mess with the Palette settings.

Similar to above, the pull down puts a set of colors into the swatches below it. You'll notice that there are two rows of 8. These swatches override the 8 ANSI foreground and 8 background colors set by terminfo.

What is important to see is that you can set these swatches to subtle color variations.

Also changes you make here affect all or most all of your text based programs which have color enabled. So be careful here. (I can't tell you how to back this up first, because I don't yet know. Take a screen shot at a minimum.)

While I don't know what all of these swatches are use for, some experimenting has deduced the following.

Before you start testing, open a few things from GNOME Terminal: a vim code editing session of bash, and another of c, a ls of your home directory, a tree run, and a tmux session. As you change things below, you'll be better able to see what is changing.

Try to make small changes at first. And be sure to click and un-click the checkbox at the bottom (further explained below).

Caution: If you set the Palette to Custom and then manually setup up the 16 color swatches as I suggest, be careful because if you again choose something else in the Built-in schemes:, it will wipe out your previous Palette settings, and if you again want Custom you'll have start all over which is a pain. (There seems to be no way to save your custom color settings, except with a screen shot, or by writing them down one by one.)

Built-in schemes: Custom -- Color palette: settings

tmux    status text                     status-backgr
tmux vi                 literals                        flow (orange)   comments&fcns   $names          var  names      ?
vi C    -               literals        types           flow (brown)    comments&fcns   macros          -               ?
vi Bash -               literals        -               flow (brown)    comments&fcns   Environ         var  names      ?               flow: brown (can't change with gnome)
Bash    -                               user@dir $
Bash ls -                               Reverse-backg                   Reverse-foregr
gcc

        black           aqua            green           orange          dark yellow    purple          blue, primary   gray (X)        <-- X=Don't care
        #000000         #01B9E0         #389400         #FF8A00         #C6CF76         #C401C4         #005EEA         #AAAAAA
        0               1               2               3               4               5               6               7
        ------------    ------------    ------------    ------------    ------------    ------------    ------------    ------------    <-- 1st set are     "normal   colors"

        ------------    ------------    ------------    ------------    ------------    ------------    ------------    ------------    <-- 2nd set are the "brighter colors" (for check box below)
        8               9               10              11              12              13              14              15
        #555555         #FF5555         #55FF55         #FFFF55         #5397FE         #FF55FF         #55FFFF         #D6D6D6
        dark gray (X)   red/orange      lime            yellow (X)      blue, medium    pink            aqua, bright    light gray (X)  <-- X=Don't care

tmux    ?                                               ?                                                               ?
tmux vi ?                                               ?                                                               ?
vi C    ?                                               ?                                                               ?
vi Bash ?                                               ?                                                               ?
Bash    ?               root@dir #                      ?                                                               ?
Bash ls ?                               x.sh            ?               directories     media files     links           ?
gcc     ?               errors                          ?                                                               ?

Finally, at the bottom, there is the Show bold text in bright colors checkbox. GNOME help says:

Bright colors for bold text

Traditionally terminals didn't clearly separate bold font weight from intense colors, often both of them were enabled together. Recent improvements, such as the introduction of true color support, and certain color schemes (e.g. Solarized) made it desirable to separate the two concepts, that is, make the brightness independent from the font weight.

...

Disable Show bold text in bright colors for the new default behavior, the complete separation of color intensity and font weight;

or enable this option for improved backward compatibility.

When checked it takes what was displayed in the top rows, and instead displays the bottom row's colors. If you check this you'll notice that some of the names from ls will change colors a bit. I think it ties into the ISO 6429 color sequences #1, "for brighter colors" in $ man dir_colors. It seems like this affects mostly ls and not vim.


WHAT DO THE COLORS LOOK LIKE FROM THE BUILT-IN SCHEMES

When the built-in schemes were tested with the color-test utility described here I see the following results, (tip compile and link with this $ gcc -Wall -lcurses color-demo.C):

Note the Show bold text in bright colors checkbox is checked. Unchecked the high and low intensity colors are the same.

  • Linux console (seems to be the original CGI color set):

enter image description here

  • xterm:

enter image description here

  • rxvt (out of order because this is closer to those above):

enter image description here

  • Tango (out of order because this is closer to Solarized below):

enter image description here

  • Solarized:

enter image description here


HOW DO I CONFIGURE MY COMMANDS TO SHOW IN COLOR?

In your /etc/.bashrc.shared (called by ~/.bashrc and /root/.bashrc), or if you don't have that in your ~/.bashrc and /root/.bashrc:

# === ADD COLOR UNLESS DUMB TERMINAL ========================================
if [ "$TERM" != "dumb" ]; then
    # ENVIRONMENT: 
    #   You can turn off these colorizing aliases in the interactive environment by invoking 
    #       shell with  TERM="dumb bash".
    
    #   Assume LS_COLORS is already set by dircolors in /etc/profile.  It can be adjusted later.
    
    # Using color to distinguish file types is disabled both by default and with --color=never.  
    #   With --color=auto, ls emits color codes only when standard output is connected to a terminal.  
     export COLOR_MODE='--color=auto'


    #   The use of  alias  limits color effects to the interactive command usage. 
    #       It has advantage over exporting environment variable "export COLOR_MODE='--color=auto'" 
    #       since color can be seen under pager programs such as less(1). If you wish to suppress 
    #       color when piping to other programs, use "--color=auto" instead in the above example 
    #       for "~/.bashrc".
    #       !! NOTE - alias is very picky about extra spaces around = sign

    # --- grep
    # Surround the matched (non-empty) strings, matching lines, context lines, file names, 
    #   line numbers, byte offsets, and separators (for fields and groups of context lines) 
    #   with escape sequences to display them in color on the terminal.  
    #   The colors are defined by the environment variable GREP_COLORS, (plural).
    #       See grep man page for GREP_COLORS instructions.
     alias  grep=' grep ${COLOR_MODE}'
     alias egrep='egrep ${COLOR_MODE}'
     alias fgrep='fgrep ${COLOR_MODE}'
     alias zgrep='zgrep ${COLOR_MODE}'

    # --- ls ------------------------
     alias ls='ls ${COLOR_MODE}'

    #   These next two use the ls alias above, i.e. the first one below is really 'ls ${LS_OPTS} -l'
     alias ll='ls -l'                   # -l = long
     alias  l='ls -lA'                  # -A = amost all (.*, but not . nor ..)

    # --- tree ----------------------
     alias tree='tree -C'               # -C adds color to tree

    # --- less ----------------------
     alias  less='less -R'              # Output raw control chars for ANSI colors

    # --- man -----------------------
    # ref: http://www.tuxarena.com/2012/04/tutorial-colored-man-pages-how-it-works/
    #   NOTE these seem to use TERMCAP which is obsolite.
    # ANSI "color" escape sequences are sequences of the form:      ESC [ ... m
        export LESS_TERMCAP_mb=$(printf '\e[01;31m')        # enter blinking            mode
        export LESS_TERMCAP_md=$(printf '\e[01;38;5;75m')   # enter double-bright       mode
        export LESS_TERMCAP_me=$(printf '\e[0m')            # turn off all appearance   modes (mb, md, so, us)

        export LESS_TERMCAP_so=$(printf '\e[01;33m')        # enter standout            mode
        export LESS_TERMCAP_se=$(printf '\e[0m')            #  leave standout           mode

        export LESS_TERMCAP_us=$(printf '\e[04;38;5;200m')  # enter underline           mode
        export LESS_TERMCAP_ue=$(printf '\e[0m')            #  leave underline          mode

fi
1
  • Man, dropping a book on knowledge on it. Thanks man
    – ruevaughn
    Feb 9, 2022 at 10:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .