Prueba de LS_COLORS en zsh

10

Hace unos años encontré un fragmento de código interesante que imprime cada tipo de archivo en su color correspondiente de acuerdo con los colores configurados LS_COLORS. Desafortunadamente, ya no puedo recordar el enlace.

Aquí está el fragmento test_colors.shen cuestión

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                                                                                                                                                                                                                                      
}   

El fragmento funciona muy bien en bash, pero no en zsh, y no puedo decir por qué. Cuando lo ejecuto zshme sale el siguiente 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

Actualización (1 de noviembre de 2011)

Probé el guión de @ Stéphane Gimenez a continuación. Noté que algunos personajes parecen no escapar correctamente. ¿Alguna idea de por qué?

Respuesta: Vea los comentarios sobre la respuesta de @ Stéphane Gimenez.

                                                      ingrese la descripción de la imagen aquí

Amelio Vazquez-Reina
fuente

Respuestas:

7

Lo mismo escrito para zsh de una manera mucho más limpia:

#!/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%s\e[m\n' $color $name
done
Stéphane Gimenez
fuente
Es posible que desee reemplazar \npor un espacio al final de la printfcompactación tal vez.
Stéphane Gimenez
Gracias @ Stéphane Gimenez. He actualizado mi OP con un problema que tengo al imprimir algunos caracteres usando su script. Sin embargo, no estoy seguro de si esto está estrictamente relacionado con su script (¿puede ser mi propio terminal?)
Amelio Vazquez-Reina
1
@intrpc: ejecutándose zshya que shestá utilizando algún modo de compatibilidad. Llame a su script como zsh ./test_color_schemeo agregue comillas dobles alrededor $colory $name.
Stéphane Gimenez
@ Stéphane Gimenez: Fui dirigido aquí desde mi pregunta relacionada aquí: unix.stackexchange.com/questions/52659/… . Su expansión de abreviaturas es muy útil. Tengo tres abreviaturas rs, cay mhque no están incluidos anteriormente. ¿Me puede decir dónde encontrar sus expansiones? Gracias.
chandra
Interpretado de dircolors -p rs = reset, ca = capacidad, mh = multi-hard_link
weldabar
3

Es necesario para escapar de la =en ${i%=*}caso contrario, el patrón sufijo =*sufre =de expansión , por lo que =se interpreta como un nombre de comando. Esta es la causa del * not founderror.

Zsh no divide las palabras en sustituciones variables de forma predeterminada, por lo que se $LS_COLORSexpande a una sola palabra. Para que el forbucle funcione en las partes separadas por dos puntos de $LS_COLORS, use for i in $=LS_COLORS. O más idiomáticamente en zsh, no use IFSpero en lugar especificar explícitamente cómo dividir: for i in ${(s.:.)LS_COLORS}.

La sintaxis ${!x}que significa "el valor de la variable cuyo nombre es $x" es específica de bash. Zsh tiene una construcción equivalente, la P bandera de la expansión de parámetro : ${(P)x}.

Gilles 'SO- deja de ser malvado'
fuente
1
Hay dos razones más para que este script no funcione en zsh. No hay división automática de palabras LS_COLORSy =debe escaparse en los patrones de sustitución.
Stéphane Gimenez
@ StéphaneGimenez Tienes razón, gracias, solo presioné donde bash no es estándar, pero estas son dos características zsh no estándar que también deben abordarse. Debes ampliar tu respuesta para tener todas las explicaciones, y luego puedo eliminar la mía.
Gilles 'SO- deja de ser malvado'