Bash-Skript - Dialog-Checkliste

663
coverflower

Ich versuche, ein Bash-Skript zu schreiben, um die Installation meiner Pakete zu automatisieren. Die Idee ist also, eine .csv-Datei (packages.csv) wie diese zu lesen:

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 

Erstellen Sie ein Array für jede Spalte (ohne Kopfzeile) und übergeben Sie die Arrays an eine Dialogprüfliste.

#!/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=("$") array2=("$") array3=("$")  let num=${#array2[*]}-1  for i in $(seq 0 $num); do list[i]=$(echo $ $ $) done  OPTION=$(dialog --checklist "Choose packages:" \ 10 60 4 \ $) exitstatus=$? if [ $exitstatus = 0 ]; then echo "$OPTION" else echo "Cancel" fi 

Ich habe es irgendwann zum Laufen gebracht, aber ohne Leerzeichen in der Beschreibung. Nachdem ich einige Änderungen vorgenommen hatte, um die Leerzeichen aufzunehmen, funktioniert es überhaupt nicht. Wie kann ich es reparieren? Eigentlich habe ich in meiner CSV-Datei mehr als 3 Spalten, aber die Bash-Checkliste erwartet 3 Argumente. Kann man sie irgendwie in die Checkliste aufnehmen?

0
Haben Sie überlegt, etwas wie [Marionette] (https://www.puppetcookbook.com/posts/install-multiple-packages.html) zu verwenden? Der Link enthält ein Beispiel für Ihren genauen Anwendungsfall. hhoke1 vor 6 Jahren 0
Nein, die Puppe scheint für diesen einfachen Fall ein Overkill zu sein. coverflower vor 6 Jahren 0
Was ist für a in $ col1; tun für? Und das gleiche für "b" und "c"? Ich denke, wenn Sie es für "b" tun, wird "$ col2" mit dem Standard "IFS" geteilt. dann erhalten Sie mehrere 'b'-s, während Sie immer noch eine einzelne Zeile analysieren. Kamil Maciorowski vor 6 Jahren 0
@ Kamil Maciorowski: Füllen Sie die 3 Arrays coverflower vor 6 Jahren 0
Ich habe dies hier gefunden: https://stackoverflow.com/questions/30146241/error-with-linux-whiptail-dialog-arguments-from-bash-variable welche funktioniert. Das mittlere Argument steht in einfachen Anführungszeichen und die linken und rechten Argumente nicht. Das muss das Problem sein, aber ich weiß nicht, wie ich es beheben kann ... coverflower vor 6 Jahren 0

1 Antwort auf die Frage

1
Kamil Maciorowski
#!/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 "$")  exitstatus=$? if [ $exitstatus = 0 ]; then echo "$option" else echo "Cancel" fi 

Hauptänderungen:

  • tail -n +2 "$input" den Header abstreifen;
  • dummyVariable, um mehr als drei Spalten zuzulassen (zusätzliche Spalten spielen keine Rolle dialog);
  • eine arrayVariable, für die eine Eingabe erstellt werden kann, dialoganstatt viele, die Daten auf verkrüppelte Weise übergeben;
  • "$" in diesem Fall eine geeignete Methode, um array als Befehlszeilenargumente zu übergeben;
  • --output-fd 1erklärt in dieser Antwort (es gibt bessere, robustere Lösungen gibt);
  • Kleinbuchstabenvariablen für diese Antwort .

Eigentlich habe .csvich in meiner Datei mehr als 3 Spalten, aber die Bash-Checkliste erwartet 3 Argumente. Kann man sie irgendwie in die Checkliste aufnehmen?

Wozu? Richtig, dialog --checklisterwartet sie drei mal drei. Halten Sie es aufgeräumt. Ich denke, vielleicht haben Sie mehr Spalten für Ihren Code benötigen, das kommt nach dialog . Beachten Sie Folgendes: Wenn dialogdie Bezeichner aus der ersten Spalte erfolgreich zurückgegeben werden und diese vorhanden sind $option, parsen Sie die Ausgabe folgendermaßen:

for package in $option; do … ; done 

(Damit dies funktioniert, packages.csvdarf Ihre erste Spalte keine Leerzeichen enthalten.)

Auf diese Weise können Sie für jedes ausgewählte Paket etwas tun. Innerhalb dieser Schleife können Sie so viele Spalten lesen, wie Sie benötigen, jedoch zuerst grepfür die richtige Zeile:

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

(Hinweis: Nachforschen read -a, siehe help read). Und dann, immer noch in der Schleife, erledigen Sie den Rest Ihrer Arbeit.