Testing LS_COLORS in zsh

A few years ago I found an interesting code snippet that prints each type of file in its corresponding color according to the colors set up in LS_COLORS. Unfortunately, I can’t remember the link anymore.

Here is the snippet test_colors.sh in question

eval $(echo "no:global default;fi:normal file;di:directory;ln:symbolic link;pi:named pipe;so:socket;do:door;bd:block device;cd:character device;or:orphan symlink;mi:missing file;su:set uid;sg:set gid;tw:sticky other writable;ow:other w
ritable;st:sticky;ex:executable;"|sed -e 's/:/="/g; s/;/"n/g')                                                                                                                                                                            
{                                                                                                                                                                                                                                           
  IFS=:                                                                                                                                                                                                                                     
  for i in $LS_COLORS                                                                                                                                                                                                                       
  do                                                                                                                                                                                                                                        
    echo -e "e[${i#*=}m$( x=${i%=*}; [ "${!x}" ] && echo "${!x}" || echo "$x" )e[m"                                                                                                                                                       
  done                                                                                                                                                                                                                                      
}

The snippet works great in bash, but not in zsh, and I can’t tell why. When I run it in zsh I get the following error:

> sh .test_colors.sh
.eval_colors:1: * not found
[00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=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:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.flac=01;35:*.mp3=01;35:*.mpc=01;35:*.ogg=01;35:*.wav=01;35:m

Update (Nov. 1, 2011)

I tested the script by @Stéphane Gimenez below. I noticed that some characters seem to not escape correctly. Any thoughts why?

Answer: See comments on @Stéphane Gimenez’s answer.

                                                      enter image description here

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The same written for zsh in a much cleaner way:

#!/bin/zsh

typeset -A names
names[no]="global default"
names[fi]="normal file"
names[di]="directory"
names[ln]="symbolic link"
names[pi]="named pipe"
names[so]="socket"
names[do]="door"
names[bd]="block device"
names[cd]="character device"
names[or]="orphan symlink"
names[mi]="missing file"
names[su]="set uid"
names[sg]="set gid"
names[tw]="sticky other writable"
names[ow]="other writable"
names[st]="sticky"
names[ex]="executable"

for i in ${(s.:.)LS_COLORS}
do
    key=${i%=*}
    color=${i#*=}
    name=${names[(e)$key]-$key}
    printf 'e[%sm%se[mn' $color $name
done

Method 2

You need to escape the = in ${i%=*} because otherwise the suffix pattern =* undergoes = expansion, so = is interpreted as a command name. This is the cause of the * not found error.

Zsh doesn’t split words on variable substitutions by default, so $LS_COLORS expands to a single word. To have the for loop operate on the colon-separated parts of $LS_COLORS, use for i in $=LS_COLORS. Or more idiomatically in zsh, don’t use IFS but instead specify explicitly how to split: for i in ${(s.:.)LS_COLORS}.

The syntax ${!x} to mean “the value of the variable whose name is $x” is specific to bash. Zsh has an equivalent construct, the P parameter expansion flag: ${(P)x}.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x