How to remove dir background in `ls -color` output
Solution 1
To remove all background colors, stick the following into your ~/.bashrc :
eval "$(dircolors -p | \
sed 's/ 4[0-9];/ 01;/; s/;4[0-9];/;01;/g; s/;4[0-9] /;01 /' | \
dircolors /dev/stdin)"
Solution 2
Quick solution:
Enter these two commands in the Bash command line:
dircolors -p | sed 's/;42/;01/' > ~/.dircolors
source ~/.bashrc
Explanation:
There is a program dircolors
intended to set up the config for ls
.
The default ~/.bashrc
script loads the config with these lines:
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
Because by default the file ~/.dircolors
does not actually exist the script uses the built-in Bash config (eval "$(dircolors -b)"
).
To remove green background for o+w
('writable by others' permission marked by last 'w
' in drwxrwxrwx
notation in ls
) directories you need to create this file basing on the current (built-in) config. In the command line type the following:
dircolors -p > ~/.dircolors
dircolor -p
prints the current config and >
redirects the output to the given file.
Now open the file in an editor and find the following line:
OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky
change the number 42
(denoting green background) to 01
(no background) and save changes. Alternatively you can do it with sed
program and its substitution feature ('s/PATTERN/NEW_STRING/'
syntax) from the command line directly:
sed -i 's/;42/;01/' ~/.dircolors
Above 2 things can be achieved by a single command using a pipe '|
':
dircolors -p | sed 's/;42/;01/' > ~/.dircolors
To get the change to take the effect (without restarting the shell), type:
source ~/.bashrc
Solution 3
LS_COLORS
is the variable that's referred by ls
for colouring its output. If LS_COLORS
isn't set, it's generated using dircolors
behind the scenes. This can be set manually too with/out using dircolors
(see Vivid below).
If most defaults work and you want only a few to be fixed, the easiest is to just set them in your .bashrc
.
LS_COLORS=$LS_COLORS:'tw=00;33:ow=01;33:'; export LS_COLORS
This replaces the background colour (42
) with normal(00
) and bold (01
) for
- Others-writable directories with sticky bit set (
tw
) - Others-writable directories without sticky bit (
ow
)
This is the simplest solution since we keep the defaults for the rest.
The other answer's technique
# -b: make dircolors generate for bash
# sed replaces offending background colors
# sed's output is fed as input for another instance of dircolors
# the entire subshell returns LS_COLORS that's `eval`uated
eval $(dircolors -b | sed 's/ 4[0-9];/ 01;/; s/;4[0-9];/;01;/g; s/;4[0-9] /;01 /' | dircolors /dev/stdin)
simply does this on the fly by getting all the colour values and replacing anything with a background (4[0-9]
) with bold (01
).
There're better alternatives avoiding all manual fiddling:
-
LS_COLORS (the project; not to be confused with
$LS_COLORS
, the variable)- Curated set of colours for different file formats/extensions
- Download latest version, evaluate and append to
.bashrc
wget https://raw.github.com/trapd00r/LS_COLORS/master/LS_COLORS -O $HOME/.config/LS_COLORS
echo 'eval $(dircolors -b "$HOME/.config/dircolors")' >> $HOME/.bashrc
-
Vivid
- Multiple themes
- Generates
LS_COLORS
on-the-fly - Set
$LS_COLORS
in.bashrc
usingvivid
command that generates necessary colour codes based on theme
export LS_COLORS="$(vivid generate molokai)"
Both these tool colour schemes don't have background colour for directories of any kind.
Solution 4
The explanation is given in the output of dircolors -p
, e.g.,
Of course dircolors
doesn't color its output. I used this script:
#!/usr/bin/perl -w
use strict;
our $comment = "\e[31m";
our $reset = "\e[K\e[m";
our @data;
open my $fh, "dircolors -p|" or die "cannot read from dircolors";
@data = <$fh>;
close $fh;
printf "\e[H\e[2J";
for my $n ( 0 .. $#data ) {
chomp $data[$n];
if ( $data[$n] =~ /^\s*#/ ) {
printf "%s%s%s\n", $comment, $data[$n], $reset;
}
elsif ( $data[$n] =~ /^\s*TERM\s/ ) {
printf "%s\n", $data[$n];
}
elsif ( $data[$n] =~ /^\s*[^\s]+\s+\d+(;\d+)?\s*(#.*)?$/ ) {
my $code = $data[$n];
$code =~ s/^\s*[^\s]+\s+//;
$code =~ s/\s.*//;
my $data = $data[$n];
$data =~ s/(#.*)$/$comment$1$reset/;
$data =~ s/^(\s*)([^\s]+)(\s+)/$1\e[${code}m$2\e[m$3/;
printf "%s\n", $data;
}
else {
printf "%s\n", $data[$n];
}
}
1;
To get rid of the background, you can either change the directory permissions, or use a different database to set your LS_COLORS
environment variable. The dircolors
documentation is the place to go.
Related videos on Youtube
chikadance
Updated on June 11, 2022Comments
-
chikadance almost 2 years
I use default Linux Mint .bashrc, here is full bashrc, the output is like:
some dir has green background, How to remove it?
-
legends2k over 3 yearsThe simplest and cleanest is
LS_COLORS=$LS_COLORS:'tw=00;33:ow=01;33:'; export LS_COLORS
, see answer below.
-
-
Alfredo Hernández over 5 yearsThey are removed for the output of
ls
, but they still show when using autocomplete in zsh. Any workaround for this? -
Rafael Kitover over 5 yearsThe colors for ls are set in the LS_COLORS environment variable, if the zsh code uses these colors it should work correctly, if it uses something else it will not work.
-
Alfredo Hernández over 5 yearsI found the issue. For some weird reason, the
eval
needs to be defined after theplugins
, but beforesource $ZSH/oh-my-zsh.sh
(I use Oh My Zsh), otherwise it's not fully loaded. -
legends2k over 3 yearsFor this method to work, I'd to put
eval "$(dircolors -b ~/.dircolors)"
in my.bashrc
as Bash 5.0.18 doesn't automatically pick up~/.dircolors
or~/.dir_colors
as the man page says on macOS 10.15.7.