Set Reliable ls Colours with dircolors
Your ls output is a wall of identical grey and you want log files, directories and archives to jump out. You will set colours for chosen file types with dircolors, test them, and load the setting in a Bourne-style shell in about ten minutes. The examples use GNU coreutils 9.4, installed here as package version 9.4-3ubuntu6.3.
The route
Jump straight to the step you need, or tick off Done means at the end.
- You need: a shell and GNU
ls. Nothing here needssudo. - What it creates: one small configuration file in your home directory. Replace
$HOMEif you keep dotfiles elsewhere. - What it will not touch: your files. Only the shell environment and the display change: nothing is renamed, edited or deleted.
1. Check the installed command
Confirm that you are running GNU coreutils before you trust any of the output below:
$ command -v dircolors
/usr/bin/dircolors
$ dircolors --version
dircolors (GNU coreutils) 9.4
The catch: dircolors does not colour anything itself. It prints shell commands that set an environment variable, and GNU ls reads that variable when colour output is on. So a correct dircolors result can still be invisible if ls is not using its colour option. Remember this when troubleshooting.
Checkpoint
The version above is the behaviour this guide describes. Other coreutils releases can ship different built-in database entries.
2. Inspect the built-in colour database
With no file argument, the installed command uses its precompiled database. Print that database rather than generating shell code:
$ dircolors --print-database | sed -n '1,45p'
# Configuration file for dircolors, a utility to help you set the
# LS_COLORS environment variable used by GNU ls with the --color option.
...
DIR 01;34
LINK 01;36
*.tar 01;31
That output is a configuration document, not something to paste into your shell. It holds three kinds of line:
- Terminal filters such as
TERM. - File-type rules such as
DIR. - Extension rules such as
*.tar.
The colour values are ANSI style codes. For example, 01;31 means bold red on a typical terminal.
To see the generated setting instead of the database, run:
$ dircolors --sh
LS_COLORS='...'
export LS_COLORS
The value can come out empty or shorter when your TERM matches no database entry. That is a terminal-selection result, not a sign that the command failed.
3. Create a small, explicit configuration
Start with a local file that applies to every terminal and colours .log files bold red. Use a quoted here document so the shell expands nothing while the file is written:
$ mkdir -p "$HOME/.config"
$ cat > "$HOME/.config/dircolors" <<'EOF'
TERM *
.log 01;31
EOF
Warning
This step creates or replaces the named configuration file. If you already have useful rules there, stop and inspect it first. Recovery is simple: restore your backup, or remove this file and go back to the built-in database.
- The leading dot is the extension-rule syntax of the database format.
- The colour value follows after whitespace.
- No shell syntax. Do not put quotes or an environment-variable assignment in this file.
Checkpoint
Inspect what you wrote before loading it.
$ sed -n '1,10p' "$HOME/.config/dircolors"
TERM *
.log 01;31
4. Generate and apply the Bourne-shell setting
Ask dircolors to read the file and emit code for shells such as Bash, Dash and Zsh:
$ dircolors --sh "$HOME/.config/dircolors"
LS_COLORS='*.log=01;31:'
export LS_COLORS
To apply that output to the current shell, evaluate only the output from the trusted file you just inspected:
$ eval "$(dircolors --sh "$HOME/.config/dircolors")"
$ printf '%s\n' "$LS_COLORS"
*.log=01;31:
Security boundary
eval executes shell syntax. Never use it with an untrusted or remotely downloaded configuration file. If the file belongs to another user, contains unexpected lines, or came from a repository you have not reviewed, inspect it before evaluating the generated output.
The change lasts only for the current shell and its children. To make it stick, add the same eval line to the startup file your shell uses, such as ~/.bashrc. Back that file up first. If a new shell misbehaves, remove the added line and start another shell.
5. Verify the rule with ls
Create a harmless test file in a temporary directory and force colour output. The command reads the directory and does not modify existing files:
$ test_dir=$(mktemp -d)
$ touch "$test_dir/example.log" "$test_dir/example.txt"
$ ls --color=always "$test_dir/example.log" | od -An -t x1 | head -n 2
1b 5b 30 6d 1b 5b 30 31 3b 33 31 6d ...
The bytes beginning 1b 5b are an escape sequence, and the 01;31 part confirms the .log rule reached ls. A terminal renders the same sequence as bold red, but the byte check also works on a non-colour display or in a captured log.
When you finish, remove only the temporary directory and its two test files:
$ rm -rf -- "$test_dir"
Destructive action
This deletion is irreversible. Check the variable name before pressing Enter, and never substitute a path that holds real data.
6. Diagnose the common traps
If dircolors --sh prints an empty assignment, check the terminal filters and the environment:
$ printf 'TERM=%s\n' "${TERM-}"
$ dircolors --print-database | grep -E '^(TERM|COLORTERM) '
$ dircolors --sh "$HOME/.config/dircolors"
- A restrictive
TERMline can stop later rules applying. The explicitTERM *in the small example avoids that while you test. Remove it only when you want terminal-specific behaviour. - Variable set, no colour? Check the
lsinvocation. Automatic colour mode normally suppresses escape sequences when standard output is not a terminal. The always-colour option is the one to use for verification. - Aliases and startup files can change the command you are really running. Use the explicit command form shown above to bypass an alias.
- C shell? Use
dircolors --cshinstead of--sh. Do not paste Bourne-shell output into a C shell startup file.
Done means
- Right command:
dircolors --versionidentifies the command you tested. - Reviewed config: your file contains reviewed
TERMand extension rules. - Correct output:
dircolors --sh FILEemits the expected environment-variable assignment. - Applied: the current shell has the assignment after the explicit
eval. - Verified: the always-colour
lscheck produces the expected escape sequence for the test extension. - Tidy: the temporary test directory is gone and no real file was changed.