Home / Alt manpages / dir_colors(5)

  • dir_colors(5)
  • File format
  • linux

Set Practical ls Colours with a dir_colors File

You will finish with a small, user-owned dir_colors file that gives directories and log files clear colours, plus a shell command that loads it into LS_COLORS. The examples target GNU dircolors 9.4 from GNU coreutils, with the dir_colors(5) format documented by Linux man-pages 6.7.

Allow about ten minutes. You need GNU dircolors, ls, and a shell. No elevated privileges are needed. The configuration affects your shell environment and directory listings, not the files being listed.

1. Check the installed tools

Start with read-only checks. This confirms which implementation will parse the file and avoids debugging a different command earlier in your PATH:

$ command -v dircolors
/usr/bin/dircolors
$ dircolors --version
dircolors (GNU coreutils) 9.4
$ command -v ls
/usr/bin/ls

Your paths or version may differ. The GNU implementation is the relevant detail here. The manual also describes statements accepted by Slackware's implementation, but GNU dircolors ignores its COLOR, OPTIONS, and EIGHTBIT statements.

Checkpoint

If dircolors is missing, stop here and use your normal package-management process. Do not copy a configuration from another operating system and assume its parser accepts every keyword.

2. Make a minimal configuration

Choose a user-owned path. The manual names /etc/DIR_COLORS and ~/.dir_colors as conventional locations, but also says those locations are ignored by GNU dircolors on Debian. Passing the path explicitly makes the source of the settings unambiguous.

First check whether a file already exists. This is read-only:

$ test -e "$HOME/.dir_colors" && ls -l "$HOME/.dir_colors" || echo 'no existing user file'

If the file exists and contains settings you want to keep, copy it before editing. This changes nothing in the original:

$ cp --preserve=mode,ownership,timestamps "$HOME/.dir_colors" "$HOME/.dir_colors.bak"

Warning

The following here-document overwrites ~/.dir_colors. Use the backup first, or open the file in an editor and merge these lines instead:

$ cat > "$HOME/.dir_colors" <<'EOF'
# Global rules apply to every terminal type.
NORMAL 0
DIR 01;34
*.log 01;31

# This rule is used when TERM matches this pattern.
TERM xterm-256color
DIR 01;36
EOF

Blank lines are ignored and text after a hash preceded by whitespace is a comment. Statements are case-insensitive. A statement before the first TERM is global; later statements belong to the matching terminal section. A later terminal-specific declaration can override a global declaration.

Checkpoint

Inspect the file before loading it:

$ sed -n '1,80p' "$HOME/.dir_colors"
# Global rules apply to every terminal type.
NORMAL 0
DIR 01;34
*.log 01;31

# This rule is used when TERM matches this pattern.
TERM xterm-256color
DIR 01;36

3. Generate LS_COLORS for the current shell

GNU dircolors reads the file and prints shell code. Use -b for Bourne-style shells such as Bash, Dash and Zsh:

$ eval "$(dircolors -b "$HOME/.dir_colors")"
$ printf '%s\n' "$LS_COLORS"
no=0:di=01;34:*.log=01;31:di=01;36:

The exact order and terminal-specific entries depend on TERM. The final di=01;36 is the matching terminal rule overriding the earlier directory rule when this terminal is xterm-256color. A generated fragment normally contains an LS_COLORS assignment and an export.

Security boundary

eval executes the text printed by dircolors. Only use it with a configuration file you trust. If you want to inspect the generated text first, run dircolors -b "$HOME/.dir_colors" without eval.

Test the result without forcing colour into a log or pipe:

$ mkdir -p /tmp/dir-colors-check
$ touch /tmp/dir-colors-check/example.log /tmp/dir-colors-check/notes.txt
$ ls --color=auto -l /tmp/dir-colors-check
total 0
-rw-r--r-- 1 ... example.log
-rw-r--r-- 1 ... notes.txt

File ownership, timestamps and spacing vary. In an interactive terminal, example.log and the directory name should use the configured styles. The automatic colour option emits colour for a terminal but avoids escape sequences when output is redirected.

4. Load the file automatically, carefully

If the manual command works, add it to the startup file for the shell you actually use. For Bash, put this line in ~/.bashrc:

eval "$(dircolors -b "$HOME/.dir_colors")"

For a C shell, generate the equivalent form with dircolors -c and adapt it for the relevant startup file:

$ dircolors -c "$HOME/.dir_colors"
setenv LS_COLORS 'no=0:di=01;34:*.log=01;31:di=01;36:'

Do not paste a Bash assignment into a C shell startup file. Likewise, do not add the line to a system-wide profile when a per-user setting is enough. Reopen a shell or source the file, then check:

$ . "$HOME/.bashrc"
$ printf 'LS_COLORS is %s\n' "${LS_COLORS:+set}"
LS_COLORS is set

If you need to undo the automatic loading, remove the line you added, then start a new shell. To undo only the current shell's exported value, run unset LS_COLORS; this does not edit the configuration file.

5. Extend the rules without surprising yourself

Use a leading asterisk for a suffix rule such as *.log. The older form .log is accepted but is described as obsolete. Type rules include DIR, FILE, LINK, FIFO, SOCK, EXEC, ORPHAN and MISSING. If ORPHAN is absent, ls falls back to the link colour; if MISSING is absent, it falls back to the regular-file colour.

Colour values are usually ANSI numbers separated by semicolons. For example, 0 resets the display, 1 makes text brighter, 31 selects a red foreground, and 44 selects a blue background. Terminals do not all render every attribute consistently. If a terminal leaves everything coloured after a listing, set both NORMAL and FILE to a reset or suitable normal foreground sequence.

Spaces, control characters, backslashes, carets and a leading hash in a value or extension need escaping. The format accepts C-style escapes such as \e for Escape, \n for newline, \_ for space and \# for a literal hash. Keep unusual control characters out of a shared configuration unless you have tested the terminal that will display them.

6. Diagnose a rule that does not apply

First print the generated fragment and check the environment:

$ printf 'TERM=%s\n' "$TERM"
$ dircolors -b "$HOME/.dir_colors"
LS_COLORS='...';
export LS_COLORS

If the terminal-specific rule is missing, its TERM pattern did not match the current TERM. Remember that the global section ends at the first TERM; move a rule above that line if it should apply everywhere. If the generated assignment looks right but ls does not colour names, check that you are using its automatic colour mode or have an alias that enables colour. LS_COLORS supplies the mapping; it does not by itself force ls to emit colour.

When a rule appears to do nothing, test a filename that actually matches it. A rule for *.log does not match a file named server.LOG, and filename case handling is not supplied by this format. Keep the temporary test directory until the listing behaves as expected, then remove it with rm -rf /tmp/dir-colour-check only when you are certain it contains no useful files.

Done means

  • You confirmed the installed GNU dircolors version and selected the correct shell output form.
  • Your configuration has a global rule and, where needed, a matching TERM section.
  • You inspected the generated shell code before using eval on a trusted file.
  • LS_COLORS is set in the intended shell and the automatic colour mode shows the expected styles.
  • You know how to remove the startup line or unset the current shell variable without changing listed files.