• 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 editor
      yad --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 field
      yad --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-result option.
      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 activated

      Tips on getting user input

      User-checking the input in YAD

      -editable Suppose 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


      find cherche 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ép Mail

       

      La liste est envoyée dans xargs qui renvoie chaque fichier dans un ls avec 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,2 on trie avec la date en ordre inverse, puis on affiche les 10 premiers : head.

      tr pour 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 paste command (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":CB we 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 ... `)

      and

      Record=(`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 --ellipsize properly and displays full width. I think it was working correctly so I must have done something to break it. I’ve tried all the START, NONE, MIDDLE and END options 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.

 

Aucun commentaire

 

Laissez un commentaire