Search code examples
bashzenity

Zenity GUI for chattr and lsattr


Description:

Hello Stackers, i'm currently making a zenity GUI for the command chattr. What i'm trying to do is to show and change the attributes of a file using zenity --list --checklist to tick the attributes that i want an so, but the main issue that i'm facing is that i do not know whats the order of lsattr output, something like: -------------e-- file

Code sample:

attr=("A" "Solo escritura" "a" "No actualizar" "c" "Comprimido" "C" "No copiar en escritura" "D" "Actualización de directorio sincrónica" "d" "Ignorar en backup" "E" "Error de compreción" "e" "Usando extents" "h" "Archivo enorme" "I" "Indexación hashed trees" "i" "Archivo inmutable" "j" "Registro de datos" "s" "Borrado seguro" "S" "Actualización sincrónica" "T" "Directorio tope" "t" "Archivo sin cola" "u" "Deshacer borrado" "X" "Acceso crudo dec compreción" "Z" "Archivo comprimido sucio" "-v" "Generar verción de archivo")

fileattr=$(lsattr "$file") ; j=0 ; k=1

for (( i=1; i<=15; i++ )); do
    [[ "${fileattr:$i:1}" != "-" ]] && values+="true ${attr[$j]} ${attr[$k]//' '/_} " && setted+="${attr[$j]} " ||\
    values+="false ${attr[$j]} ${attr[$k]//' '/_} "
    ((j+=2)) ; ((k+=2))
done

zenity --list --checklist --column="Estado" --column="Atributo" --column="Descripción" ${values}

Code explanation:

  1. attr is an array and is ordered using this page
  2. The for loop runs 15 times (it's equal to the amount of file attributes returned by lsattr), and in each go it validates for not setted attributes "-", if an attribute is set then append "true attr[j] attr[k]" to values and append the attribute to setted (for later on purposes) or append "false attr[j] attr[k]" to values
  3. Finally call zenity with the collected values

Launching output:

Zenity window It tells me that the "s" attribute is set but thats not true because the lsattr output is -------------e-- file. I have noticed that there are more attributes in the page than in the lsattr output

Note:

I know, maybe i'm not using the correct aproach, so if you can find a better way to do it, i'm all ears.

Thanks.


Solution

  • Associative arrays will be useful in this task.

    Let's define a list of all the possible attributes:

    valueList=acdeijstuACDST
    

    Let's define an associative array to store the values:

    declare -A valueMap
    

    Initialize the map with all false values for all attributes:

    for ((i = 0; i < ${#valueList}; i++)); do
        name=${valueList:i:1}
        valueMap[$name]=false
    done
    

    Loop over characters in fileattr to update values in the map to true:

    for ((i = 0; i < 16; i++)); do
        name=${fileattr:i:1}
        [[ $name != - ]] && valueMap[$name]=true
    done
    

    Combine valueMap and your original attr to create an array of values to pass to Zenity:

    zenityValues=()
    for ((i = 0; i < ${#attr[@]}; i+=2)); do
        name=${attr[i]}
        description=${attr[i+1]}
        zenityValues+=(${valueMap[name]} "$name" "$description")
    done
    

    And finally call Zenity as you did, but passing zenityValues as an array:

    zenity ... "${zenityValues[@]}"