跳到主要内容
ansicode

LS_COLORS —— ls、dircolors、文件列表的 ANSI 颜色

GNU `ls` 每次调用都会读取 `LS_COLORS` 环境变量 —— 一个冒号分隔的 `type=SGR` 与 `*.ext=SGR` 串,按文件类型和尾缀给每个条目着色。BSD 派生的 `ls`(macOS、FreeBSD、OpenBSD)读取完全不同的环境变量 `LSCOLORS`,格式为固定位置 22 字符且不支持扩展名。下方七段复制即用片段覆盖完整 LS_COLORS 地图:环境变量语法、`dircolors` 工作流、BSD 分歧、GNU 权威默认值、`eza` / `exa` 扩展、`--color` / `NO_COLOR` / `CLICOLOR` 覆盖、以及 bash / zsh / fish / csh 的按 shell 接线。

配置片段

LS_COLORS —— 冒号分隔的 key=value 字符串语法

GNU `ls --color=auto` 每次调用都会读取 `LS_COLORS` 环境变量。它是单个由冒号分隔的 `key=SGR` 串。键有两类:**类型标记**(两字母助记符匹配文件类型 —— `di` 目录、`ln` 符号链接、`ex` 可执行、`fi` 普通文件、`pi` 管道 / FIFO、`so` 套接字、`bd` 块设备、`cd` 字符设备、`or` 悬空符号链接、`mi` 缺失目标、`tw` 可写粘滞目录、`ow` 可写他人目录、`st` 粘滞目录、`su` setuid、`sg` setgid、`ca` capability、`mh` 多硬链接、`do` Solaris door)和**扩展名标记**(`*.ext=SGR` 模式按尾缀匹配,默认大小写敏感 —— 不支持 glob 匹配,只支持精确尾缀)。值是去掉前导 `\x1b[` 与末尾 `m` 的 SGR 参数串:`01;31` = 粗体红前景、`38;5;208` = 256 调色板橘、`38;2;255;128;0` = 24 位真彩色。标记从左到右首次命中,后续条目覆盖前面。

shell / env
# Minimal LS_COLORS — a few type tokens + a few extension tokens:
export LS_COLORS='di=01;34:ln=01;36:ex=01;32:*.tar=01;31:*.zip=01;31:*.gz=01;31:*.md=00;33'

# What each pair means:
#   di=01;34         directories          → bold blue
#   ln=01;36         symlinks             → bold cyan
#   ex=01;32         executables          → bold green
#   *.tar=01;31      .tar files           → bold red
#   *.zip=01;31      .zip files           → bold red
#   *.gz=01;31       .gz files            → bold red
#   *.md=00;33       .md files            → yellow

# 256-palette + truecolor (coreutils 8.32+, 2020):
export LS_COLORS='di=38;5;33:*.json=38;2;255;128;0'
#   di=38;5;33       directories          → palette index 33 (blue)
#   *.json=38;2;…    .json files          → orange 24-bit

# Important: case-sensitive by default. Match .JPG separately from .jpg
# unless you set TZ-style insensitivity via dircolors --print-database flags.
export LS_COLORS='*.jpg=01;35:*.JPG=01;35:*.png=01;35:*.PNG=01;35'

# Verify the env var is set, paged for readability:
echo "$LS_COLORS" | tr ':' '\n'

dircolors —— 把可读数据库转换为 LS_COLORS

手写一个巨长的冒号分隔字符串很痛苦。`dircolors` 接受一个多行、注释友好的数据库(每行一个键、`# 注释`、节标题)然后输出 `LS_COLORS=…; export LS_COLORS` shell 命令。多数发行版自带 `/etc/DIR_COLORS`(只读)加用户可编辑的 `~/.dir_colors`。`dircolors -p` 把内置默认输出到 stdout —— 管道进文件后编辑,然后在 `.bashrc` 中 `eval $(dircolors -b ~/.dir_colors)`。输出格式 shell 感知:`-b` 输出 bash / sh 语法,`-c` 输出 csh / tcsh 语法。Fish 用户需要不同的接线 —— 见片段 7。

shell / env
# 1. Generate a template — built-in default, fully commented:
dircolors -p > ~/.dir_colors

# Sample contents look like:
#
#   # Files of special type
#   DIR    01;34       # directory
#   LINK   01;36       # symbolic link (a 'target' here for ls -l)
#   EXEC   01;32       # files with execute permission
#
#   # Archives or compressed (bright red)
#   .tar   01;31
#   .tgz   01;31
#   .zip   01;31
#
#   # Image formats (bright magenta)
#   .jpg   01;35
#   .png   01;35

# 2. Edit ~/.dir_colors to taste, then wire it into ~/.bashrc:
echo 'eval "$(dircolors -b ~/.dir_colors)"' >> ~/.bashrc

# 3. Reload the shell or:
eval "$(dircolors -b ~/.dir_colors)"

# Verify it landed:
ls --color=always | head

# csh / tcsh form:
eval \`dircolors -c ~/.dir_colors\`

BSD ls —— LSCOLORS 是完全不同的格式(本页最大差异化)

macOS、FreeBSD、OpenBSD、NetBSD 自带 BSD 派生的 `ls` —— 它不读 `LS_COLORS`。它读 `LSCOLORS`(注意:没有下划线)且格式是固定位置的 22 字符串,每对字符按硬编码顺序为某个文件类型槽位编码(前景, 背景):`目录 · 符号链接 · 套接字 · 管道 · 可执行 · 块设备 · 字符设备 · setuid · setgid · 粘滞他人可写 · 他人可写`。每个字符为 `a-h`(小写 = 颜色)/ `A-H`(大写 = 粗体颜色)/ `x`(默认)。字母映射:`a=黑 b=红 c=绿 d=褐 / 黄 e=蓝 f=品红 g=青 h=浅灰`。**不支持按扩展名着色** —— BSD `ls` 仅按类型着色,绝不按 `.tar` / `.zip` 尾缀。`ls -G` 启用颜色(BSD 默认关)或在 env 中 `CLICOLOR=1`;管道时强制开 `CLICOLOR_FORCE=1`。多数跨平台 dotfile 同时设置 `LS_COLORS` 和 `LSCOLORS`,让同一份 `~/.bashrc` 在 Linux 和 macOS 都能用。

shell / env
# BSD LSCOLORS — 11 pairs (22 chars), hard-coded slot order:
#
#   pos  slot                           default
#   1-2  directory                      ex      (blue, default-bg)
#   3-4  symlink                        fx      (magenta, default-bg)
#   5-6  socket                         cx      (green, default-bg)
#   7-8  pipe / FIFO                    dx      (brown / yellow, default-bg)
#   9-10 executable                     bx      (red, default-bg)
#   11-12 block device                  egcx    -- wait, this is wrong;
#                                                  the canonical slot is:
#         block device                  cd      (green, brown)
#   13-14 char device                   ed      (blue, brown)
#   15-16 setuid                        ab      (black, red)
#   17-18 setgid                        ag      (black, cyan)
#   19-20 sticky+other-writable         hb      (light-gray, red)
#   21-22 other-writable                hc      (light-gray, green)
#
# Letter map (BSD-specific, NOT ANSI / SGR numerics):
#   a=black b=red c=green d=brown e=blue f=magenta g=cyan h=light-gray
#   uppercase = bold version of the same colour
#   x         = default terminal colour
#
# BSD ls colour default — the value of LSCOLORS if you don't set it:
export LSCOLORS='exfxcxdxbxegedabagacad'

# Enable colour on BSD ls — default-off, opposite of GNU ls:
export CLICOLOR=1            # honour TTY detection
export CLICOLOR_FORCE=1      # force on pipe (skip if you pipe to grep)

# Verify with ls -G (BSD-flag) or just ls (when CLICOLOR is set):
ls -G

# Cross-platform dotfile — set BOTH so Linux + macOS work from the same file:
export LS_COLORS='di=01;34:ln=01;36:ex=01;32:*.tar=01;31:*.zip=01;31'
export LSCOLORS='ExFxCxDxBxegedabagacad'      # uppercase = bold on BSD

# Or just install GNU coreutils on macOS for unified behaviour:
#   brew install coreutils
#   alias ls='gls --color=auto'
# Then LS_COLORS applies on macOS too.

权威的 GNU LS_COLORS 默认值 —— 可复制粘贴

如果你只想要一行可粘贴的、`dircolors -p | dircolors --bourne-shell` 在 GNU coreutils 9.x 上会产出的默认值 —— 见下方。保存到 `.bashrc` 就有上游默认而无需运行 `dircolors` —— 在最小化容器 / Alpine / scratch 镜像 / distroless 等可能没有 `dircolors` 的场景特别有用。类型标记在前,扩展名标记按颜色分组(归档红、图片品红、音频青、源码默认)。最后写入的覆盖前面,故较窄的扩展覆盖应放在广义类型标记之后。

shell / env
# Canonical GNU coreutils 9.x default LS_COLORS, one line:
export LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=00:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:'

# Notes on the special type tokens at the front:
#   rs=0            reset (delimits coloured regions in a row)
#   mh=00           multi-hardlink — empty value = use default
#   pi=40;33        pipe / FIFO  → black bg, yellow fg
#   so=01;35        socket       → bold magenta
#   do=01;35        Solaris door → bold magenta
#   bd=40;33;01     block dev    → black bg, bold yellow fg
#   cd=40;33;01     char dev     → black bg, bold yellow fg
#   or=40;31;01     orphan link  → black bg, bold red fg
#   mi=00           missing target — empty = use default
#   su=37;41        setuid       → white fg, red bg
#   sg=30;43        setgid       → black fg, yellow bg
#   ca=00           capability — empty = use default (capabilities deprecated)
#   tw=30;42        sticky + other-writable → black fg, green bg
#   ow=34;42        other-writable          → blue fg, green bg
#   st=37;44        sticky                  → white fg, blue bg
#   ex=01;32        executable              → bold green

eza / exa —— 现代 ls 替代品及其自定义颜色系统

`exa`(已弃用,最后提交 2022)及其活跃维护的派生 **`eza`** 是流行的 `ls` 替代品。为向后兼容它们也读 `LS_COLORS`,但同时支持自己的更丰富按元素颜色环境变量 `EXA_COLORS` / `EZA_COLORS`,包含 GNU `ls` 没有的额外槽位:文件权限(`ur` 用户读、`uw` 用户写、`ux` 用户执行,以及 `gr` `gw` `gx` `tr` `tw` `tx` 组 / 他人)、inode 列(`in`)、大小单位后缀(`sn` 大小数字、`sb` 大小字节单位)、日期列(`da` 重点日期、`df` 未来日期等)、git 状态列(`ga` 新增、`gm` 修改、`gd` 删除、`gn` 重命名、`gv` 更新)。同样的 `key=SGR` 语法。如希望纯自定义调色板,先 `EZA_COLORS=reset` 丢弃默认。

shell / env
# Minimal eza override — keep LS_COLORS, add eza-specific slots:
export EZA_COLORS='ur=33:uw=31:ux=32:gr=33:gw=31:gx=32:in=38;5;240:sn=38;5;33:sb=38;5;240'

# What each pair means in eza output:
#   ur=33        user read         → yellow
#   uw=31        user write        → red
#   ux=32        user execute      → green
#   gr=33        group read        → yellow
#   gw=31        group write       → red
#   gx=32        group execute     → green
#   in=38;5;240  inode column      → 256-palette dim grey
#   sn=38;5;33   size number       → palette blue
#   sb=38;5;240  size byte unit    → palette dim grey

# eza git-status column slots (only when --git is passed):
export EZA_COLORS='ga=32:gm=33:gd=31:gn=35:gv=36:ga|gm|gd|gn|gv=01'
#   ga=32        added             → green
#   gm=33        modified          → yellow
#   gd=31        deleted           → red
#   gn=35        renamed           → magenta
#   gv=36        updated           → cyan

# Reset eza defaults and start from a clean slate:
export EZA_COLORS='reset:ur=33:uw=31:ux=32'

# Same syntax for the older exa binary:
export EXA_COLORS='reset:ur=33:uw=31:ux=32'

# Aliases for ls drop-in:
alias ls='eza --color=auto'
alias ll='eza -l --git --color=auto'
alias la='eza -la --color=auto'
alias tree='eza --tree --color=auto'

--color 标志 · NO_COLOR · CLICOLOR · CLICOLOR_FORCE —— 单次调用覆盖

GNU `ls` 接受 `--color={auto,always,never}`。`auto`(多数发行版 `LS_COLORS` 设置后的默认)仅在 TTY 上发出 SGR;`always` 强制颜色即便管道(配合 `less -R` 有用);`never` 禁用。通用 `NO_COLOR` 环境变量(coreutils 8.30 / 2018 起)覆盖一切 —— 等效于 `--color=never`。BSD `ls` 用不同标志:`-G` 启用颜色(默认关)、`CLICOLOR=1` env 等价、`CLICOLOR_FORCE=1` 通过管道强制颜色。`eza` / `exa` 镜像 GNU 的 `--color` 标志且尊重 `NO_COLOR`。提示:只在管道到渲染器(`less -R`、`bat`、`aha`)时用 `--color=always` —— 把颜色管到 `grep` / `wc` 会把 SGR 注入匹配字符串,破坏朴素子串匹配。

shell / env
# GNU ls — three colour modes:
ls --color=auto         # TTY-only (the sensible default)
ls --color=always       # force colour through pipes
ls --color=never        # disable colour entirely
NO_COLOR=1 ls           # universal env opt-out (coreutils 8.30+)

# Pipe coloured listing into a pager that renders SGR:
ls --color=always -la | less -R

# BSD ls — different flag set:
ls -G                   # one-shot enable (BSD-only flag)
CLICOLOR=1 ls           # env equivalent
CLICOLOR_FORCE=1 ls | grep .conf   # force through pipe (BSD)

# eza / exa equivalents:
eza --color=always -la | bat
NO_COLOR=1 eza          # honoured

# Defeat parent shell's alias for one invocation:
\\ls                    # bypasses alias, runs the binary directly
command ls --color=never

# Common trap — colour bytes break grep substring matching:
ls --color=always | grep ".conf"       # wrong — may miss matches
ls --color=never  | grep ".conf"       # right — clean bytes
ls --color=always | grep --color=never ".conf"   # right — strip in grep

# Verify NO_COLOR is honoured site-wide (coreutils, grep, ripgrep, etc.):
env | grep -i color
NO_COLOR=1 ls && NO_COLOR=1 grep '' file.txt && NO_COLOR=1 rg pattern

按 shell 接线 —— bash · zsh · fish · csh

`LS_COLORS` 是普通 env 变量;任何能导出 env 的 shell 都能设置。每个 shell 接线不同。`bash` 与 `zsh` 共享 `eval $(dircolors -b)` 模式。`fish` 更友好 —— `set -gx LS_COLORS …` 直接生效,且 fish 自带每元素颜色,可通过 `set fish_color_*` 配置。`csh` / `tcsh` 需要 `dircolors -c`(csh 语法输出)与 `setenv`。macOS bash 用户会踩双坑:`~/.bashrc` 仅在非登录 shell 运行,但 Terminal.app 启动登录 shell —— env 导出请放 `~/.bash_profile`(macOS 默认 zsh 时放 `~/.zprofile`)。

shell / env
# ~/.bashrc (Linux) or ~/.bash_profile (macOS Terminal.app):
if [ -r ~/.dir_colors ]; then
    eval "$(dircolors -b ~/.dir_colors)"
else
    eval "$(dircolors -b)"
fi
alias ls='ls --color=auto'

# ~/.zshrc / ~/.zprofile (macOS default since 10.15):
if (( $+commands[dircolors] )); then
    eval "$(dircolors -b ~/.dir_colors 2>/dev/null || dircolors -b)"
fi
alias ls='ls --color=auto'

# ~/.config/fish/config.fish:
if command -q dircolors
    eval (dircolors -c ~/.dir_colors 2>/dev/null | sed 's/setenv/set -gx/')
end
alias ls 'ls --color=auto'

# Or use fish's native per-element colours instead of LS_COLORS:
set -gx fish_color_command       green
set -gx fish_color_param         normal
set -gx fish_color_quote         yellow
set -gx fish_color_error         red --bold
set -gx fish_color_autosuggestion 8a8a8a

# ~/.cshrc / ~/.tcshrc:
eval \`dircolors -c ~/.dir_colors\`
alias ls 'ls --color=auto'

# macOS double-trap reminder — these only run on LOGIN shell:
#   ~/.bash_profile, ~/.zprofile, ~/.profile
# These only run on NON-login (subshell) shell:
#   ~/.bashrc, ~/.zshrc
# Terminal.app spawns login shells; iTerm2 + VS Code terminal default
# to non-login. Source one from the other for symmetry:
#   echo '[ -r ~/.bashrc ] && . ~/.bashrc' >> ~/.bash_profile

本站覆盖周边 ANSI / ls / pager 生态的相邻页面。