-
yad > exemples de scripts
Logout dialog
#! /bin/bash action=$( yad --width 300 --entry --title "System Logout" \ --image=gnome-shutdown --button="Switch User:2" --button="gtk-ok:0" --button="gtk-close:1" \ --text "Choose action:" --entry-text "Power Off" "Reboot" "Suspend" "Logout" ) ret=$? [[ $ret -eq 1 ]] && exit 0 if [[ $ret -eq 2 ]] ; then gdmflexiserver --startnew & exit 0 fi case $action in Power*) cmd="sudo /sbin/poweroff" ;; Reboot*) cmd="sudo /sbin/reboot" ;; Suspend*) cmd="sudo /bin/sh -c 'echo disk > /sys/power/state'" ;; Logout*) case $(wmctrl -m | grep Name) in *Openbox) cmd="openbox --exit" ;; *FVWM) cmd="FvwmCommand Quit" ;; *Metacity) cmd="gnome-save-session --kill" ;; *) exit 1 ;; esac ;; *) exit 1 ;; esac eval exec $cmd
Run dialog
#! /bin/bash XTERM="xterm" # create history file mkdir -p ${XDG_CACHE_HOME:-$HOME/.cache}/ HISTFILE=${XDG_CACHE_HOME:-$HOME/.cache}/ix-run.history touch $HISTFILE # create and run dialog TITLE="Run command" TEXT="\nEnter command to execute:\n" rcmd=$( 'yad --width=500 --center --window-icon="gtk-execute" --name="${0##*/}" --title="$TITLE" \ --text="$TEXT" --image="gtk-execute" --entry --editable --rest="$HISTFILE" ) [[ -z "$rcmd" ]] && exit 0 # run command case $rcmd in http://*|https://*|ftp://*) xdg-open $rcmd & ;; mailto://*) xdg-email $rcmd & ;; man://*) eval $XTERM -e "man ${rcmd#man://}" & ;; telnet*|ssh*) eval $XTERM -e "$rcmd" & ;; *) eval $rcmd & ;; esac # add command to history grep -q -F "$rcmd" $HISTFILE || sed -i "1 i $rcmd" $HISTFILE exit 0
Autostart editor
#! /bin/bash config_dir=${XDG_CONFIG_HOME:-$HOME/.config} results=$(mktemp --tmpdir autostart.XXXXXXXXXX) for f in $config_dir/autostart/*.desktop; do grep -m 1 -e '^[[:blank:]]*Exec' $f | cut -d = -f 2 grep -m 1 -e '^[[:blank:]]*Name' $f | cut -d = -f 2 grep -m 1 -e '^[[:blank:]]*Comment' $f | cut -d = -f 2 done | yad --width=500 --height=300 --title="Autostart editor" --image="gtk-execute" \ --text="Add/remove autostart items" --list --editable --print-all \ --multiple --column="Command" --column="Name" --column="Description" > $results if [[ ${PIPESTATUS[1]} -eq 0 ]]; then rm -f $config_dir/autostart/*.desktop i=0 cat $results | while read line; do eval $(echo $line | awk -F'|' '{printf "export NAME=\"%s\" COMMENT=\"%s\" COMMAND=\"%s\"", $2, $3, $1}') cat > $config_dir/autostart/$i$NAME.desktop << EOF [Desktop Entry] Encoding=UTF-8 Name=$NAME Comment=$COMMENT Exec=$COMMAND StartupNotify=true Terminal=false EOF $((i++)) done unset NAME COMMENT COMMAND fi rm -f $results exit 0
Graphical frontend for su
#! /bin/bash # some defaults user="root" suargs="-p" force="no" # parse commandline if [[ $# -eq 0 ]]; then echo "Usage: ${0##*/} [-f] [-u user] [--] " exit 1 fi OPTIND=1 while getopts u: opt; do case "$opt" in f) force="yes" ;; u) user="$OPTARG" ;; esac done shift $((OPTIND - 1)) cmd="$*" if [[ $force != "no" ]]; then # check for sudo sudo_check=$(sudo -H -S -- echo SUDO_OK 2>&1 &) if [[ $sudo_check == "SUDO_OK" ]]; then eval sudo $cmd exit $? fi fi # get password pass=$(yad --class="GSu" --text="password for <b>$user</b>:" --image="dialog-password" --entry --hide-text) [[ -z "$pass" ]] && exit 1 # grant access to xserver for specified user xhost +${user}@ &> /dev/null # run command fifo_in="$(mktemp -u --tmpdir gsu.empty.in.XXXXXXXXX)" fifo_out="$(mktemp -u --tmpdir gsu.empty.out.XXXXXXXXX)" LC_MESSAGES=C empty -f -i $fifo_in -o $fifo_out su $suargs $user -c "$cmd" [[ $? -eq 0 ]] && empty -w -i $fifo_out -o $fifo_in "word:" "$pass\n" exit $?
Discussion
combo-boxes and spin buttons to form dialog
By default, initial value should be the first entry in the list.
To get a little complicate, add another option says "init-val". This option can either be some value to be added to the existing list as initial value or a number specifying the location of initial value in existing list. Examples:
yad --entry "one" "two" "three" #"one" is initial value yad --entry "one" "two" "three" --init-val "zero" #"zero" is initial value yad --entry "one" "two" "three" --init-val 1 #"two" is initial value (count start from 0)
yad --form --field="combo:CB" 'test1!test2!test3' give you what you want
here is the simple form like a .desktop entry editoryad --title="Desktop entry editor" --text="Simple desktop entry editor" \ --form --field="Type:CB" --field="Name" --field="Generic name" \ --field="Comment" --field="Command:FL" --field="Icon" \ --field="In termianl:CHK" --field="Startup notify:CHK" \ "Application!URI" "Name" "Generic name" "This is the comment" \ "/usr/bin/yad" "yad" FALSE TRUE
I have tried to use yad in those situations:$ yad --form --field="Label:DIR" --item-separator="\$" \ --field="labelys:CB" 'DATA$data$basta' /home/xbg|(null)| <<- in this situation CB flag does not works < WHY? $ yad --form --item-separator="\$" --field="labelys:CB" 'DATA$data$basta' basta|
you miss data for first fieldyad --form --field="Label:DIR" --item-separator="\$" --field="labelys:CB" $HOME 'DATA$data$basta'
would works…by default yad prints result only for buttons with even return codes. for changing this behavior add--always-print-resultoption.make a checkbox (:CHK) be checked by default :by settings initial values in extra arguments :yad --form --field entry1 --field check1:chk --field entry2 --field check2:chk '' true '' false
in above example first check entry will be activatedTips on getting user input
User-checking the input in YAD
-editableSuppose the user has entered data in a form dialog like the one below, which defaults to the pipe character (|) as separator for output items. The example dialog is contained in a BASH script called ‘demo’:#!/bin/bash yad --form --field="Nom" --field="Prénom" --field="Date de naissance (JJ/MM/AAAA)"
—> retour :
Bloggs|Fred|456/12/1985|Hop hop hop. le jour est 456. No problem, we can help him by offering a confirmation dialog in which his previous entries are editable. First we’ll send the output of the YAD form dialog to a temp file, then extract each of the data entries from that file with the cut command, using the pipe character as delimiter (-d’|’):
#!/bin/bash yad --form --field="Nom" --field="Prénom" --field="Date de naissance (JJ/MM/AAAA)" > /tmp/entries nom=$(cut -d'|' -f1 < /tmp/entries) prenom=$(cut -d'|' -f2 < /tmp/entries) naissance=$(cut -d'|' -f3 < /tmp/entries)
Puis, we’ll echo those entries back into a YAD ‘text-info’ dialog with the -editable option, storing the edited (or not) result in a variable:
#!/bin/bash yad --form --field="Nom" --field="Prénom" --field="Date de naissance (JJ/MM/AAAA)" > /tmp/entries nom=$(cut -d'|' -f1 < /tmp/entries) prenom=$(cut -d'|' -f2 < /tmp/entries) naissance=$(cut -d'|' -f3 < /tmp/entries) final=$( echo -e "Nom:\t$nom\nPrenom:\t$prenom\nDate:\t$naissance" \ | yad --text-info --editable --width="300" --height="200" --text="Tout est OK ?")
Editing is done by Mr Bloggs:
YAD va retourner tous les caractères (\n et \t compris). Mais, nous avons output in a variable, we can replace the tab and newline characters with a single space simply by echoing the variable (echo $final):
Last name: Bloggs Firs name: Fred Date of birth: 16/12/1985
and we can remove the entry-prompts and replace spaces with pipes using sed commands:
foo="Last name: Bloggs Firs name: Fred Date of birth: 16/12/1985" echo $foo Last name: Bloggs Firs name: Fred Date of birth: 16/12/1985 echo $foo | sed 's/[A-Z][a-z]*: /|/g' |Bloggs |Fred |16/12/1985 echo $foo | sed 's/[A-Z][a-z]*: /|/g;s/^|//' Bloggs |Fred |16/12/1985 echo $foo | sed 's/[A-Z][a-z]*: /|/g;s/^|//;s/ |/|/g' Bloggs|Fred|16/12/1985
The finished script is shown below; it includes a ‘get me out of here!’ cancel for the text-info dialog:
#!/bin/bash yad --form --field="Nom" --field="Prénom" --field="Date de naissance (JJ/MM/AAAA)" > /tmp/entries nom=$(cut -d'|' -f1 < /tmp/entries) prenom=$(cut -d'|' -f2 < /tmp/entries) naissance=$(cut -d'|' -f3 < /tmp/entries) final=$( echo -e "Nom:\t$nom\nPrenom:\t$prenom\nDate:\t$naissance" \ | yad --text-info --editable --width="300" --height="200" --text="Tout est OK ?") if [[ $? == 1 ]] ; then rm /tmp/entries exit else [[ $? == 0 ]] echo $final | sed 's/[A-Z][a-z]*: /|/g;s/^|//;s/ |/|/g' rm /tmp/entries fi exit
Scripting a fancy chooser for recently used files
Afficher les 10 derniers fichiers modifiés en ordre chronologique inverse, avec deux fichiers sélectionnés :
Voici le code :
#! /bin/bash find ~ ! -path $HOME/'\.*' -and ! -path $HOME/'Mail*' -type f -mtime -2 \ | xargs ls -l --time-style=long-iso \ | awk '{print $6,$7,$8}' \ | sort -rk1,1 -rk2,2 \ | head \ | tr ' ' '\t' > /tmp/raw paste <(awk -F/ '{print $NF}' /tmp/raw) /tmp/raw > /tmp/table10 choices=$(awk -F"\t" '{print "<b>"$1"</b>\n<span color=\"green\">"$2" — "$3"</span>"}' /tmp/table10 \ | yad --list --multiple --column=File --separator="" --width=300 --height=600 --center \ --ellipsize=middle --title="Recent Files") if [[ -z $choices ]]; then rm /tmp/raw /tmp/table10 && exit 0 else echo "$choices" \ | sed 's/<b>\(.*\)<\/b>/\1/' \ | while read line; do xdg-open $(awk -v OPEN="$line" '$1 ~ OPEN {print $4}' /tmp/table10); done fi rm /tmp/raw /tmp/table10 exit 0
EXPLICATIONS
find ~ ! -path $HOME/’\.*’ -and ! -path $HOME/’Mail*’ -type f -mtime -2
findcherche dans le rép /home/moi (~) des fichiers (type -f) modifiés les deux dernières 24 heurs (-mtime -2). Excluant (!) les fichiers ou dossiers cachés (commençant par.) et les fichiers du répMailLa liste est envoyée dans
xargsqui renvoie chaque fichier dans unlsavec comme option une sortie en ‘long listing format’ (-l) et le format de date ISO 8601 (--time-style=long-iso) :-rw-r--r-- 1 moi moi 456 2015-08-10 19:51 /home/moi/projets/test/contacts
On récupère la date (6ème colonne), l’heure (7ème) et le chemin complet (8ème) grâce à AWK :
awk ‘{print $6,$7,$8}’La date devient donc le 1er champs, l’heure le 2ème et le chemin le 3ème.
sort -rk1,1 -rk2,2on trie avec la date en ordre inverse, puis on affiche les 10 premiers :head.trpour remplacer les espaces par des tabulations.Le résultat est enregistré dans /tmp/raw
On récupère le nom du fichier (AWK avec
/comme séparateur de champs -F/ ) et afficher le dernier champs ($NF) de chaque ligne.The extracted filenames are then joined to each line in the temp file with the
pastecommand (line 10) with a tab as default separator, and the result is saved to a new temp file, /tmp/table10:The table /tmp/table10 is now the working file for the chooser dialog, which I build with YAD. I want the YAD dialog to display each filename in bold, and under each filename the modification date and time in green (no special reason, just suits my color sense). To do this I tweak the text of each line in /tmp/table10 with AWK, adding the old-fashioned HTML markup for bold font (<b>) and a newline (line 12), and this time telling AWK that the field separator is a tab (-F"\t"). When I pipe the marked-up lines to YAD, YAD reads the markup as Pango markup and displays the text the way I want (see first illustration, above).
The other YAD options I use (lines 13 and 14) set the size and position of the dialog, its type (list) and the output separator (none), and allow me to make multiple selections from the list (--multiple). YAD also allows me to set where the ellipsis (…) goes in filenames too long for the width of the dialog (see 6th file in list in first illustration, above). Note that YAD only outputs the selected line in the dialog (the filenames), not the entire line as piped from AWK.
The selections I make are saved in the variable ‘choices’ (line 12). If I decide to cancel or close the YAD window, the script deletes my temp files and exits (lines 16 and 17). If I OK the selections, ‘choices’ is echoed (line 19) to sed to remove the bolding markup from the filename (line 20).
In line 21 I again use AWK, this time in a while loop. As each line with its selected filename is read by BASH, AWK looks for that filename in the first field in /tmp/table10. When it finds the line with that filename, AWK prints the full path to that file, which is the 4th field in the line (see above). For each selected filename, the full path is now passed to xdg-open, which opens the file with the default application for that file type.
The script then deletes the temp files and exits, leaving me with the selected files open on my desktop.
Multiple-item data entry with YAD
yad --form --field="Last name"
yad --title="" --text="coucou" --image="/home/moi/monImage.svg" --form --field="Nom"
yad --width=400 --title="" --text="coucou" --image="/chemin/vers/image.svg" --form --field="nom" --field="prénom"
le retour sera de la forme : monNom|monPrenom|
pour changer le séparateur de données
--separator="\t"(pour une tabulation par exemple)combo box
Les choix sont séparés par des
!. For example, for the field--field="Last holiday":CBwe might specify ‘un!deux!trois‘.On peut choisir le caractère de séparation par une virgule par exemple :
--item-separator=","et alors mes données seront ‘un,deux,trois‘.On doit renseigner les champs également avant le Select (par
""pour dire vide) :yad --width=400 --text="coucou" --form --field="nom" --field="prenom" --field="Last holiday":CB "" "" 'un!deux!trois'
I can choose ‘other’, delete it and type in ‘Melbourne’:
Probably the most useful combo box trick is that the combo box list can be read from a variable, keeping the code clearer:
holidays=$(echo "Gold Coast,Bali,Phuket,Sydney,other") yad --width=400 --title="" --text="coucou" --image="/chemin/image.svg" \ --form --item-separator="," --field="nom" --field="prénom" --field="Last holiday":CBE "" "" "$holidays"
The last field I’ll add to the form is a multi-line text entry one, of type :TXT. Note below that I’ve also added another field ‘placeholder’ in the last line of the code for the new, last field:
holidays=$(echo "Gold Coast,Bali,Phuket,Sydney,other") yad --width=400 --title="" --text="coucou" --image="/chemin/image.svg" --form --item-separator="," \ --field="nom" --field="prenom" --field="Last holiday":CBE --field="Liste":TXT "" "" "$holidays" ""
return
Smith|Jack|8 September 1991|Melbourne|Mum’s bangers and mash\nLamb curry\nHawaiian-style pizza|In other words, the newlines in the entered, multi-line text are reported by YAD as newline characters (\n).
Yet another nice feature of YAD is shown in the image below, which comes from one of my scripts to manage scientific data.
NOTE : the first three fields are grayed-out? The entries in these three fields come from other dialogs and were fed to this YAD dialog as the variables genus, species and event. Here are the relevant parts of the code:
yad --form --separator='\t' --field="Genus":RO --field="Species":RO --field="Event code":RO \ ... $genus $species $event "" 'ANIC!AusMus!NMV!QldMus!QVMAG!SAM!WAM!other' "" "" 'R. Mesibov!other' "" "" ""
UN AUTRE
I have a large list of directories in an array. I perform CRUD operations on the array. Each time the array is displayed with yad it starts at top of array. I would like to position the list to the last array entry accessed. I’ve set the first field to true but it only shows as selected and doesn’t position the list to that section of array.I’ve tried piping the directory name into yad (it’s searchable on column 2) by trying:echo "$DirName" | Record=(`yad --list ... `)
andRecord=(`yad --list ... `) <<< "$DirName"
The complete code is:
Record=(`yad --list --radiolist --separator="|" --grid-lines=hor \ --title="bafman - Born Again File Manager - $DirCnt Directories" \ --text="Navigate to directory and double-click or space bar to use:\ Tag files / Edit comments / Hide Dir buttons." \ --width=1200 --height=800 --center --no-markup \ --button="Tag files":$ButnTag --button="Run command":$ButnCommand \ --button="Edit comments":$ButnComment \ --button="Add Dir":$ButnAdd --button="Hide Dir":$ButnHide \ --button="Update Dirs":$ButnUpdate --button="$VariableCloseText":$ButnCancel \ --button="Save":$ButnSave \ --wrap-width=800 --wrap-cols=2 --dclick-action \ --ellipsize=START --ellipsize-cols=8 \ --search-column=2 --column "Select" \ --column "Searchable Directory Name (just start typing)" \ --column "Modified":HD --column "Owner":HD --column "Status":HD \ --column "File Cnt":NUM --column "File Sizes":SZ --column "Comment...":TXT \ --column "Tag Cnt":NUM --column "Tag Sizes":SZ \ "${DirsArr[@]}"`) Action=$?
Above code is called in while loop as directories are added, hidden, edited and tagged.The "Comments…" column doesn’t--ellipsizeproperly and displays full width. I think it was working correctly so I must have done something to break it. I’ve tried all theSTART,NONE,MIDDLEandENDoptions but the column is still width of longest element.To summarize:1) Is it possible to position yad --list to specific section of array?2) Why are comments not being ellipsized?If I understood this, you want to add new rows without closing the list dialog.I made this little script as an example. You can add folders to the list several times by clicking on "Add Folders" button.
This is only an example not ment for too many folders. :) Just a few to see how you can add more data to the list.#!/bin/bash test -e /tmp/yadpipe03 && rm -f /tmp/yadpipe03 # Named pipe initialization export PIPE_03=/tmp/yadpipe03 mkfifo $PIPE_03 exec 3<> $PIPE_03 function load_data { DIRS="$(yad --file --multiple --width=800 --height=600 --directory --title="Select Folders")" OIFS=$IFS IFS="|" [[ ! -z "$DIRS" ]] && YAD_DATA=($(for DIR in "$DIRS" ; do echo "$DIR" ; done )) IFS=$OIFS for DATA in "${YAD_DATA[@]}";do echo True # Adds "True" for the checklist column echo "${DATA}" done } export -f load_data function clear_all { echo -e '\f' } export -f clear_all # Main Dialog Record=($(yad --list --checklist --separator="|" --grid-lines=hor \ --width=1200 --height=800 --center --title="Nafman" --text="Example" \ --column "Select" --column "Folder" \ --button="Add Folders!gtk-add":'bash -c "load_data > $PIPE_03"' \ --button="Clear!gtk-clear":'bash -c "clear_all > $PIPE_03"' \ --button="OK!gtk-ok":0 \ --listen --print-all < $PIPE_03)) Action=$? echo ${Record[@]}
I hope it helps.