Bash Script - Dialog Checklist Issue

I'm trying to to write a bash script to automate the installation of my packages. So the idea is to read a .csv file (packages.csv) like this one:

pkg,Description,option
wget,file downloader,on
curl,tool to transfer data from or to a server,on
nano,text editor for Unix-like computing systems,off
emacs,An extensible customizable free/libre text editor — and more,on

build an array for each column (without header) and then pass the arrays to a dialog checklist.

#!/bin/bash

input="packages.csv"
while IFS=',' read -r col1 col2 col3
do 
    for a in $col1; do
        array_col1+=("$a") 
    done

    for b in $col2; do
        array_col2+=("$b")
    done

    for c in $col3; do
        array_col3+=("$c")
    done        

done < "$input"

array1=("${array_col1[@]:1}")
array2=("${array_col2[@]:1}")
array3=("${array_col3[@]:1}")

let num=${#array2[*]}-1

for i in $(seq 0 $num); do
    list[i]=$(echo ${array1[i]} ${array2[i]} ${array3[i]})
done

OPTION=$(dialog --checklist "Choose packages:" \
10 60 4 \
${list[*]})
exitstatus=$?
if [ $exitstatus = 0 ]; then
    echo "$OPTION"
else
    echo "Cancel"
fi

I did get it working at some point but without any spaces in the description. After I did some changes in order to include the spaces it doesn't work at all. How can I fix it? Actually in my .csv file I have more than 3 columns but bash checklist expects 3 arguments. Is it possible to somehow include them in the checklist?

5

1 Answer

#!/bin/bash

input="packages.csv"
while IFS=',' read -r col1 col2 col3 dummy
do
   array+=("$col1")
   array+=("$col2")
   array+=("$col3")
done < <(tail -n +2 "$input")

option=$(dialog --checklist --output-fd 1 "Choose packages:" 10 60 4 "${array[@]}")

exitstatus=$?
if [ $exitstatus = 0 ]; then
    echo "$option"
else
    echo "Cancel"
fi

Main changes:

  • tail -n +2 "$input" to strip the header;
  • dummy variable to allow more than three columns (extra columns don't matter to dialog);
  • one array variable to build input for dialog instead of many that pass data in a crippled way;
  • "${array[@]}" as a proper way to pass array as command line arguments in this case;
  • --output-fd 1 explained in this answer (there are better, more robust solutions there);
  • lowercase variables per this answer.

Actually in my .csv file I have more than 3 columns but bash checklist expects 3 arguments. Is it possible to somehow include them in the checklist?

What for? True, dialog --checklist expects them three by three. Keep it tidy. I guess maybe you need more columns for your code that comes after dialog. Consider this: when dialog successfully returns identifiers from the first column and you have them in $option, parse its output like this:

for package in $option; do … ; done

(For this to work your first column in packages.csv cannot contain spaces etc.)

This way you can do something for every chosen package. Inside this loop you can read as many columns as you need anew, but first grep for the proper line:

IFS=',' read -r col1 col2 col3 col4 col5 col6 dummy < <(grep "^${package}," "$input")

(Hint: investigate read -a, see help read). And then, still inside the loop, do the rest of your job.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Chloe Bennett

Chloe Bennett

Culture, Media & Entertainment Columnist

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.

Share this article
Twitter Facebook Pinterest