Je cherche un modèle bash qui utilise zenity ou yad à maintenir une liste de dossiers. Le modèle peut être une liste de contrôle d'achat avec option d'impression ou une liste de serveurs pour surveiller l'heure du ping. Dans les deux cas, je voudrais prendre ce code et l’adapter à mes besoins.
Voici un exemple de maquette de boîte de dialogue:
La boîte de dialogue permet de sélectionner un enregistrement et de cliquer sur les boutons suivants:
Insert before
(insérer avant l'enregistrement sélectionné). Un nouveau formulaire de saisie est monté pour entrer dans les champs.Edit
(éditer l'enregistrement sélectionné). Monte le même formulaire que "Insérer avant" sauf avec les valeurs existantes affichées.Delete
(supprimer l'enregistrement sélectionné). Le contenu de l'enregistrement existant est affiché et une confirmation est demandée.Run
- exécute un long processus de mise à jour qui met à jour la colonne d'état avec “MatcheOK/Different/Error”. L'utilisateur est invité à exécuter la mise à jour sur l'enregistrement sélectionné ou sur tous les enregistrements. La barre d’affichage de la progression s’affiche lorsque tous les enregistrements sont traités.Cancel ALL
- NE PAS enregistrer les modifications et quitter le script bash. Pressage Escape ou fermer la fenêtre en cliquant sur X
effectue la même action. Si des enregistrements ont été modifiés, une confirmation est demandée.Save
- enregistre les modifications sur le disque et quitte le script bash.REMARQUE: Il semble que la zénité autorise uniquement le ré-étiquetage des boutons "OK" et "Annuler". Les nouveaux boutons ne peuvent pas être définis dans zenity. En tant que tel yad (Y et A nother D ialog) qui est installé par défaut sous Ubuntu et basé sur zenity, est le chemin à parcourir. Cependant, la zénité reste dans la question car un script basé sur celui-ci peut être facilement converti en yad.
J'ai googlé des exemples existants et ceux-ci sont les plus proches, mais loin d'être satisfaisants:
tilisez zenity à partir d'un fichier script pour insérer/afficher des données en SQL
Exemple de champ déroulant trop long pour tenir dans la fenêtre
tilisation de yad (Yet Another Dialog) un fork de Zenity pour plusieurs boutons
exemples yad de Source Forge pour mettre hors tension/redémarrer/suspendre/déconnecter
REMARQUE: Je ne cherche pas une solution complète mais quelque chose de proche qui puisse être adapté à ce projet. Bien que ce projet utilise un fichier texte plat, un script existant qui utilise SQL, ISAM ou RDMS peut être adapté. Le seul impératif est qu'il soit écrit en bash et non en python, Perl ou C, etc.
Est-ce que quelqu'un peut indiquer un script bash existant qui utilise zenity (ou yad) pour insérer/modifier/supprimer des enregistrements?
YAD est une branche de Zenity et fournit des contrôles avancés sur les boutons, les listes et les interfaces GTK. Par exemple, lorsque vous entrez un nom de fichier dans cette réponse, YAD nous fournit facilement l’interface système graphique standard:
La fenêtre principale masque la colonne du numéro d’enregistrement que vous pouvez révéler à des fins de débogage:
La même fenêtre est utilisée pour insérer des enregistrements avant un enregistrement existant ou pour éditer un enregistrement existant:
Remarquez le champ "Nom de fichier". Lorsque vous y entrez, la boîte de dialogue de sélection de fichier de la première section apparaît.
Voici le code bash permettant à l'exemple YAD d'insérer/modifier/supprimer un modèle d'enregistrements. Notez qu'il faut encore un codage pour lire dans le fichier et ajouter une logique de traitement pour la commande "Exécuter". Un codage supplémentaire est probablement nécessaire pour prendre en charge les noms de fichiers avec des espaces incorporés, mais cela n’a pas encore été testé.
#!/bin/bash
# NAME: websync
# PATH: $HOME/bin
# DESC: Provide list of files and corresponding website addresses.
# DATE: Mar 25, 2017.
# NOTE: Uses yad which is fork of zenity which is GUI fork of dialog.
# TODO: Add local file date modified. Add Answer last revision date.
# Add question title.
# Add file Word count, or size, or ignore as irrelevant?
# Add answer Word count if file Word count is displayed.
# Add answer up votes.
# Scan directory to add all files. ("Populate" button)
# Initialize $ListArr[@] < /home/$USER/bin/.websync
# Use "|" as ListArr delimeter or (double quotes?) for file names with spaces
# Must have the yad package.
command -v yad >/dev/null 2>&1 || { echo >&2 "yad package required but it is not installed. Aborting."; exit 99; }
# Must have the zenity package.
command -v zenity >/dev/null 2>&1 || { echo >&2 "yad package required but it is not installed. Aborting."; exit 99; }
RenumberListArr () {
# This is called after inserting or deleting records.
# Record numbers may not be sequential because user can sort on any column
# Record nubmers must be unique as they are used to find the correct record in ListArr array.
# Matching on "file name" or any other field is impossible because there may be duplicate names.
# Define variables for easy reading and fewer code line changes when expanding
RecArrCnt=5
ListArrCnt=${#ListArr[@]}
i=1 # First element (0) is "false", followed by record number element (1)
j=1 # Record numbers start at 1
while [ $i -lt $ListArrCnt ] ; do
ListArr[$i]=$j
j=$(($j + 1))
i=$(($i + $RecArrCnt))
# echo "Renumber i: $i j: $j"
done
}
OLDIFS="$IFS"
IFS="|"
ListArr=()
# TODO: Replace this section with IFS=' ' read -ra CfgArr < /home/$USER/bin/.websync
ListArr=("${ListArr[@]}" false "1" "/usr/local/bin/display-auto-brightness" "Different")
Modified=$(stat "/usr/local/bin/display-auto-brightness" | grep "Modify:"| cut -f2 -d" ")
echo "Modified: $Modified" # File modified date is a future list array new field
ListArr=("${ListArr[@]}" "http://askubuntu.com/questions/894460/automatically-adjust-display-brightness-based-on-sunrise-and-sunset/894470#894470")
ListArr=("${ListArr[@]}" false "2" "/usr/local/bin/Sun-hours" "Matches")
ListArr=("${ListArr[@]}" "http://askubuntu.com/questions/894460/automatically-adjust-display-brightness-based-on-sunrise-and-sunset/894470#894470")
ListArr=("${ListArr[@]}" false "3" "/etc/cron.daily/Sun-hours" "Matches")
ListArr=("${ListArr[@]}" "http://askubuntu.com/questions/894460/automatically-adjust-display-brightness-based-on-sunrise-and-sunset/894470#894470")
ListArr=("${ListArr[@]}" false "4" "/home/rick/.conkyrc" "Matches")
ListArr=("${ListArr[@]}" "http://askubuntu.com/questions/894460/automatically-adjust-display-brightness-based-on-sunrise-and-sunset/894470#894470")
ListArr=("${ListArr[@]}" false "5" "/usr/local/bin/auto-brightness-config" "Matches")
ListArr=("${ListArr[@]}" "http://askubuntu.com/questions/894460/automatically-adjust-display-brightness-based-on-sunrise-and-sunset/894470#894470")
ListArr=("${ListArr[@]}" false "6" "/etc/cron.d/display-auto-brightness" "Matches")
ListArr=("${ListArr[@]}" "http://askubuntu.com/questions/894460/automatically-adjust-display-brightness-based-on-sunrise-and-sunset/894470#894470")
ListArr=("${ListArr[@]}" false "7" "/home/rick/bin/indicator-sysmonitor-display" "Different")
ListArr=("${ListArr[@]}" "http://askubuntu.com/questions/882419/can-bash-display-in-systray-as-application-indicator/882420#882420")
TransCount=0 # Number of Inserts, Edits and Deletes
# Read Only Status column: Recalc, Different, Matches, Bad File, No Address, Bad Address
# Debugging: --hide-column=2 hides Read Only record number column for normal operation
while true ; do
# adjust width & height below for your screen 900x600 default for 1920x1080 HD screen
# also adjust font="14" below if blue title text is too small or too large
Record=(`yad \
--title "websync - Compare local scripts to those published on internet." --list \
--text '<span foreground="blue" font="14"> \
Click column heading to sort.\
Select record before clicking: Insert / Edit / Delete</span>' \
--width=1200 --height=600 --center --radiolist -separator="$IFS" \
--button="Insert before":10 --button="Edit":20 --button="Delete":30 --button="Run":40 \
--button="Cancel ALL":50 --button="Save":60 --search-column=3 \
--column "Select" --column "Record number" --hide-column=2 --column "File Name" \
--column "Status" --column " Website Address" \
"${ListArr[@]}"`)
Action=$?
RecSelected=false
RecArr=()
i=0
# Button values 1 and 3 don't work for returning selected record for some reason???
# Button values 11, 13 and 15 don't work either. 12, 14 and 16 work.
# Therefore use Button values (10, 20, 30...) for readability.
for Field in "${Record[@]}" ; do
RecSelected=true
RecArr[i++]=$Field
done
# Define variables for easy reading and fewer code line changes when expanding
RecArrCnt=5
ListArrCnt=${#ListArr[@]}
# Error checking
if [[ $Action == 10 ]] || [[ $Action == 20 ]] || [[ $Action == 30 ]] ; then
if [[ $RecSelected == false ]] ; then
zenity --error --text 'You must select a record before clicking: Insert / Edit / Delete.'
continue
fi
fi
# Insert before || or Edit ?
if [[ $Action == 10 ]] || [[ $Action == 20 ]] ; then
RecArr[3]="Recalc"
# --text="Set fields and click OK to update"
# Note if there is a space at end of line, next line generates invalid command error from yad
NewRecArr=(`yad --width=900 --height=300 --title="Link file to Website Address" \
--form --center \
--field="File name":FL --field="Status":RO \
--field="Website Address":TXT \
${RecArr[2]} ${RecArr[3]} ${RecArr[4]}`)
ret=$?
# Cancel =252, OK = 0
# OK & Insert operation?
if [[ $ret == 0 ]] && [[ $Action == 10 ]]; then
# Create new list entry and renumber
((TransCount++)) # Update number of changes
let i=1 # Base 0 array, record number is second field
while [ $i -lt $ListArrCnt ] ; do
if [ ${ListArr[$i]} -eq ${RecArr[1]} ]; then
# We have matching record number to insert before
NewArr+=( false )
NewArr+=( "${ListArr[$i]}" )
NewArr+=( "${NewRecArr[0]}" )
NewArr+=( "${NewRecArr[1]}" )
NewArr+=( "${NewRecArr[2]}" )
fi
let j=$(( $i-1 ))
let k=$(( $j+$RecArrCnt ))
while [ $j -lt $k ] ; do
NewArr+=( "${ListArr[$j]}" )
j=$(($j + 1))
done
let i=$(($i + $RecArrCnt)) # Next list array entry to copy
done
ListArr=("${NewArr[@]}")
unset NewArr
RenumberListArr
# OK & Edit operation?
Elif [[ $ret == 0 ]] && [[ $Action == 20 ]]; then
# Update array entry
((TransCount++))
let i=1
while [ $i -lt $ListArrCnt ] ; do
if [ ${ListArr[$i]} -eq ${RecArr[1]} ]; then
# We have matching record number
ListArr[++i]="${NewRecArr[0]}"
ListArr[++i]="New"
ListArr[++i]="${NewRecArr[2]}"
let i=$(($ListArrCnt + 1)) # force exit from while loop
else
let i=$(($i + $RecArrCnt)) # Check next entry
fi
done
fi
# Delete record?
Elif [[ $Action == 30 ]] ; then
# --text="click OK to confirm delete"
# Note if there is a space at end of a script line, the next line generates
# "invalid command error from yad
yad --width=900 --height=300 --title="Do you really want to delete this record?" \
--text '<span foreground="blue" font="14">Click OK to confirm delete.</span>' \
--form --center \
--field="File name":RO --field="Status":RO \
--field="Website Address":RO \
${RecArr[2]} ${RecArr[3]} ${RecArr[4]}
ret=$?
# Cancel =252, OK = 0
if [[ $ret == 0 ]] ; then
# Delete record from list array and renumber
((TransCount++))
let i=1
while [ $i -lt $ListArrCnt ] ; do
if [ ${ListArr[$i]} -eq ${RecArr[1]} ]; then
# We have matching record number
j=$(($i - 1))
k=$(($j + $RecArrCnt))
while [ $j -lt $k ] ; do
unset 'ListArr[$j]'
j=$(($j + 1))
done
for i in "${!ListArr[@]}"; do
NewArr+=( "${ListArr[$i]}" )
done
ListArr=("${NewArr[@]}")
unset NewArr
let i=$(($ListArrCnt + 1)) # force exit from while loop
else
let i=$(($i + $RecArrCnt)) # Check next entry
fi
done
RenumberListArr
else
continue # cancel changes.
fi
# Run update process?
Elif [[ $Action == 40 ]] ; then
continue # TODO: Run
# Cancel all changes?
Elif [[ $Action == 50 ]] || [[ $Action == 252 ]] ; then
# Cancel ALL || or X the window or Escape
if [[ $TransCount -gt 0 ]] ; then
zenity --question --text "You have made $TransCount change(s). Do you really want to cancel?"
rc=$?
if [[ $rc -eq 0 ]] ; then
exit
fi
else
exit
fi
# Save changes?
Elif [[ $Action == 60 ]] ; then
# Save
echo ${ListArr[@]} > ~/bin/.websync
exit
else
zenity --error --text "~/bin/websync - Unknown button return code: $Action"
exit
fi
done # End of while loop
IFS="$OLDIFS"
exit
J'espère que cela économisera beaucoup de temps aux autres utilisateurs qui utiliseront leur système de gestion des enregistrements en utilisant bash
et yad
. Bien sûr, plus de méthodes à l'épreuve des balles et probablement plus rapides peuvent être utilisées avec Python ou C, mais cela se fait probablement au détriment de davantage de lignes de code et d'une courbe d'apprentissage plus élevée.
En fin de compte, ce projet s'adresse à ceux qui souhaitent en savoir plus sur bash et sur ce qui peut être accompli dans un environnement réservé à Bash.
Peut-être que AskUbuntu est le mauvais forum pour publier ceci et les forums Stack Overflow ou Unix & Linux pourraient être de meilleurs candidats Stack Exchange. J'ai hâte de faire des commentaires à ce sujet car je ne suis vraiment pas sûr du meilleur endroit.
Bien sûr, j'attends toujours des commentaires généraux et des critiques constructives :)