Menguji LS_COLORS dalam zsh


10

Beberapa tahun yang lalu saya menemukan potongan kode menarik yang mencetak setiap jenis file dalam warna yang sesuai sesuai dengan warna yang diatur dalam LS_COLORS. Sayangnya, saya tidak dapat mengingat tautannya lagi.

Inilah cuplikan yang test_colors.shdimaksud

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                                                                                                                                                                                                                                      
}   

Cuplikan bekerja dengan baik bash, tetapi tidak dalam zsh, dan saya tidak tahu mengapa. Ketika saya menjalankannya, zshsaya mendapatkan kesalahan berikut:

> 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

Pembaruan (1 November 2011)

Saya menguji skrip dengan @ Stéphane Gimenez di bawah ini. Saya perhatikan bahwa beberapa karakter tampaknya tidak melarikan diri dengan benar. Adakah pemikiran mengapa?

Jawab: Lihat komentar pada jawaban @ Stéphane Gimenez.

                                                      masukkan deskripsi gambar di sini

Jawaban:


7

Tulisan yang sama untuk zsh dengan cara yang jauh lebih bersih:

#!/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

Anda mungkin ingin mengganti \ndengan spasi di bagian akhir printfuntuk kekompakan mungkin.
Stéphane Gimenez

Terima kasih @ Stéphane Gimenez. Saya telah memperbarui OP saya dengan masalah yang saya dapatkan ketika mencetak beberapa karakter menggunakan skrip Anda. Tidak yakin apakah ini benar-benar terkait dengan skrip Anda (mungkin ini terminal saya sendiri?)
Amelio Vazquez-Reina

1
@ intrpc: berjalan zshkarena shAnda menggunakan beberapa mode kompatibilitas. Panggil skrip Anda sebagai zsh ./test_color_schemeatau tambahkan tanda kutip ganda di sekitar $colordan $name.
Stéphane Gimenez

@ Stéphane Gimenez: Saya diarahkan ke sini dari pertanyaan terkait saya di sini: unix.stackexchange.com/questions/52659/… . Perluasan singkatan Anda sangat membantu. Saya memiliki tiga singkatan rs,, cadan mhitu tidak termasuk di atas. Bisakah Anda memberi tahu saya di mana menemukan ekspansi mereka? Terima kasih.
chandra

Diterjemahkan dari dircolors -p rs = reset, ca = kapabilitas, mh = multi-hard_link
weldabar

3

Anda perlu melarikan diri ke =dalam ${i%=*}karena jika pola sufiks =*mengalami =ekspansi , maka =ditafsirkan sebagai nama perintah. Ini adalah penyebab * not foundkesalahan.

Zsh tidak membagi kata pada substitusi variabel secara default, jadi $LS_COLORSperluas satu kata saja. Agar forloop beroperasi pada bagian yang dipisahkan oleh titik dua $LS_COLORS, gunakan for i in $=LS_COLORS. Atau lebih ideomatik di zsh, jangan gunakan IFSmelainkan menentukan secara eksplisit bagaimana membagi: for i in ${(s.:.)LS_COLORS}.

Sintaks yang ${!x}berarti "nilai variabel yang namanya $x" adalah khusus untuk bash. Zsh memiliki konstruk setara, yang P bendera ekspansi parameter : ${(P)x}.


1
Ada dua alasan lagi mengapa skrip ini tidak berfungsi di zsh. Tidak ada pemisahan kata otomatis untuk LS_COLORSdan =perlu melarikan diri dalam pola substitusi.
Stéphane Gimenez

@ StéphaneGimenez Anda benar, terima kasih, saya hanya menemukan di mana bash adalah non-standar tetapi ini adalah dua fitur zsh non-standar yang perlu ditangani juga. Anda harus memperluas jawaban Anda untuk memiliki semua penjelasan, dan kemudian saya dapat menghapus jawaban saya.
Gilles 'SO- stop being evil'
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.