This is a follow-up to my previous reply. It will walk you through the process and hopefully help you understand what's going on. You can jump straight to the summary in the end if you feel like it.
Determining what exactly bash is doing and where colors come from in our listing
The program ls is parf of the GNU core utilities (coreutils package), as confirmed by running:coreutils have complete documentation accessible withThere is a menu on this main page. The tenth item is exactly what we're looking for: Directory listing. Use Tab to jump to the next hypertext link and press Enter once the cursor is on Directory listing menu item. It opens another node and right there we can see four items under its menu:
Code:
* ls invocation:: List directory contents.
* dir invocation:: Briefly ls.
* vdir invocation:: Verbosely ls.
* dircolors invocation:: Color setup for ls, etc.
The last one looks really promising! So let's place the cursor on it and jump to its page! No. Hold on. Open a new terminal tab and try entering dircolors. Since it is a program, the command will be recognized. Let's look at what it outputs:
Code:
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=30;41: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:*.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:';
export LS_COLORS
Aha! A long list of some extensions, some of which are recognizable, and some color values assigned to them. Pay attention to the beginning: there is an assignment statement to an environment variable called LS_COLORS and the variable itself is exported in the end. Now, let's go back to the manual. If you accidentally closed it, fret not. Use this command to invoke that page again:It tells us that there is a sequence of commands to set up the terminal for color output from ls, but how exactly does it happen? We can move around pages with Pg Up and Pg Dn keys. Right in the end, it gives a description of the '--print-database' option:
Code:
‘-p’
‘--print-database’
Print the (compiled-in) default color configuration database. This
output is itself a valid configuration file, and is fairly
descriptive of the possibilities.
Let's try it!
Code:
A very long, multipage output…
Notice how file extensions and their color values are listed one per line and the format is rather strange and may seem arcane. Hmm, maybe pipe it through the less pager?
Code:
dircolors --print-database | less
Ah, much better! Let's try reading through it. Anything right of a number sign (#) are comments and are not treated as instructions. Again, use arrow keys or Pg Up and Pg Dn to move around. Second batch of comments includes some interesting lines:
Code:
# Below are the color init strings for the basic file types. A color init
# string consists of one or more of the following numeric codes:
# Attribute codes:
# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
# Text color codes:
# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
# Background color codes:
# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
Understanding file mode bits
It looks like we are going to have to either disable the background color for directories or set it to something else, but how do we do that to directories? They don't have extensions, after all! Luckily, Linux isn't Windows. Everything is a file and every file can be determined by its type.The very first character d that appears in the long format listing indicates that it is a directory. It is the return of a stat(2) system call. We probably have to look for a line that says "dir(ectory)". Sure enough, there is one:
Code:
DIR 01;34 # directory
Let's try to parse it. The first word is self-explanatory: it means the following color codes are assigned to files of type directory. From the comments above, we deduce that 01 is the bold attribute and 34 is the color blue. Hmm, that doesn't make any sense. There is no background color set, so how come there is background on our listing? We are going to have to dig deeper. In our directory listing, we had a dozen of directories with identical file mode bits, i.e. drwxrwxrwx. Let's read up on this. According to info ls:
Code:
‘-l’
‘--format=long’
‘--format=verbose’
In addition to the name of each file, print the file type, file
mode bits, number of hard links, owner name, group name, size, and
timestamp (*note Formatting file timestamps::), normally the
modification timestamp (the mtime, *note File timestamps::). Print
question marks for information that cannot be determined.
The file type is one of the following characters:
‘-’
regular file
‘b’
block special file
‘c’
character special file
‘C’
high performance (“contiguous data”) file
‘d’
directory
Earlier we said that the d really stands for directory (file type). Well, what about the other nine letters? They are file mode bits. Let's invoke info again:
Code:
Basics
* Common options: (coreutils)Common options.
* Coreutils: (coreutils). Core GNU (file, text, shell) utilities.
* Date input formats: (coreutils)Date input formats.
* Ed: (ed). The GNU line editor
* File permissions: (coreutils)File permissions.
Access modes.
Move your cursor to the File permissions link and press Enter. It opens a new document, from which we select Mode Structure. There is the explanation:
Code:
The file mode bits have two parts: the “file permission bits”, which
control ordinary access to the file, and “special mode bits”, which
affect only some files.
There are three kinds of permissions that a user can have for a file:
1. permission to read the file. For directories, this means
permission to list the contents of the directory.
2. permission to write to (change) the file. For directories, this
means permission to create and remove files in the directory.
3. permission to execute the file (run it as a program). For
directories, this means permission to access files in the
directory.
There are three categories of users who may have different
permissions to perform any of the above operations on a file:
1. the file’s owner;
2. other users who are in the file’s group;
3. everyone else.
Configuring the color setup to our liking
The r stands for read permissions (permission to list directory contents), the w–for write permissions (permission to create and remove files in the directory), and the x–for execute permissions (permission to access files in the directory). The first set of the three permissions belong to the file's owner (u for short), the second set belongs to other users who are in the file's group (g for short) and the third–to everyone else (o for short). We now understand that these directories are other-writable, i.e. the third set includes all permissions and permissions for others (aka everyone else, the world) to write specifically. Well, let's go back to our database now. Scrolling further down a bit we encounter this line with a concise comment that explains it:
Code:
OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky
34 is for blue foreground and 42 is for green background. Yes! This is exactly what we were looking to modify. The question is how? With these six simple steps:
- Save the current configuration file to our home directory with an appropriate name .dircolors.
Code:
dircolors --print-database > ~/.dircolors
- Open this file with our favorite text editor.
- Edit this line, so that other-writable directories appear in the same colors as ordinary directories, which is 01;34, and keep the comment intact.
Code:
OTHER_WRITABLE 01;34 # dir that is other-writable (o+w) and not sticky
Code:
OTHER_WRITABLE 30;42 # this will set foreground color to black, background color remains unchanged, i.e. green
- Put the following lines in your ~/.bashrc (per info dircolors).
Code:
d=.dircolors
test -r $d && eval "$(dircolors $d)"
- Restart your terminal or source the .bashrc file.
- That's it! Enjoy!
Okay, maybe that wasn't six steps at all…
See also
info ls, info dircolors, dir_colors(5), console_codes(4)
Color codes are conformant to ECMA-48/ISO 6429/ANSI X3.64, Set Graphics Rendition section. console_codes(4) and https://en.wikipedia.org/wiki/ANSI_e...on)_parameters have the full list of escape codes.
Bookmarks