Using Zenity to maintain configuration file












4














I need to setup a configuration file in Bash and believe Zenity is the best method but am having problems finding a link using google with a suitable example.



So far my code looks like this:



#!/bin/bash

zenity --forms --title="Laptop Adaptive Brightness" --text="Set Configuration"
--add-entry="/sys/class/backlight/??????/brightness"
--add-entry="Night time (min) value"
--add-entry="Day time (max) value"
--add-entry="Minutes after sunrise to max"
--add-entry="Minutes before sunset to min"

exit


and the resulting screen looks like this:



Adaptive Brightness Config



If values can't be preassigned to Zenity variables then I could put the current value into the field label ie:



   --add-entry="Night time (min) value (Current: $min)", 


And the user can leave the field blank to remain the same or enter a new value.



I'm still missing the best way of extracting Zenity fields to bash variables and writing them to the configuration file. Also I'm missing the code to read from configuration file to bash variables.



I'd appreciate a link to a Zenity example or a full answer would be even better. Thank you.



PS When I run the above script an error is reported when it completes:



$ adaptive-brightness-configGtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
||||


I'm a little confused by this and if you can point out what I'm doing wrong that would be appreciated too.










share|improve this question


















  • 4




    Probably you're overestimating Zenity's capabilities... I would make a simple GUI with Python (using Tk, GTK, Qt or whatever you want) instead of restricting myself to Bash+Zenity.
    – Byte Commander
    Feb 27 '17 at 0:35
















4














I need to setup a configuration file in Bash and believe Zenity is the best method but am having problems finding a link using google with a suitable example.



So far my code looks like this:



#!/bin/bash

zenity --forms --title="Laptop Adaptive Brightness" --text="Set Configuration"
--add-entry="/sys/class/backlight/??????/brightness"
--add-entry="Night time (min) value"
--add-entry="Day time (max) value"
--add-entry="Minutes after sunrise to max"
--add-entry="Minutes before sunset to min"

exit


and the resulting screen looks like this:



Adaptive Brightness Config



If values can't be preassigned to Zenity variables then I could put the current value into the field label ie:



   --add-entry="Night time (min) value (Current: $min)", 


And the user can leave the field blank to remain the same or enter a new value.



I'm still missing the best way of extracting Zenity fields to bash variables and writing them to the configuration file. Also I'm missing the code to read from configuration file to bash variables.



I'd appreciate a link to a Zenity example or a full answer would be even better. Thank you.



PS When I run the above script an error is reported when it completes:



$ adaptive-brightness-configGtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
||||


I'm a little confused by this and if you can point out what I'm doing wrong that would be appreciated too.










share|improve this question


















  • 4




    Probably you're overestimating Zenity's capabilities... I would make a simple GUI with Python (using Tk, GTK, Qt or whatever you want) instead of restricting myself to Bash+Zenity.
    – Byte Commander
    Feb 27 '17 at 0:35














4












4








4


3





I need to setup a configuration file in Bash and believe Zenity is the best method but am having problems finding a link using google with a suitable example.



So far my code looks like this:



#!/bin/bash

zenity --forms --title="Laptop Adaptive Brightness" --text="Set Configuration"
--add-entry="/sys/class/backlight/??????/brightness"
--add-entry="Night time (min) value"
--add-entry="Day time (max) value"
--add-entry="Minutes after sunrise to max"
--add-entry="Minutes before sunset to min"

exit


and the resulting screen looks like this:



Adaptive Brightness Config



If values can't be preassigned to Zenity variables then I could put the current value into the field label ie:



   --add-entry="Night time (min) value (Current: $min)", 


And the user can leave the field blank to remain the same or enter a new value.



I'm still missing the best way of extracting Zenity fields to bash variables and writing them to the configuration file. Also I'm missing the code to read from configuration file to bash variables.



I'd appreciate a link to a Zenity example or a full answer would be even better. Thank you.



PS When I run the above script an error is reported when it completes:



$ adaptive-brightness-configGtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
||||


I'm a little confused by this and if you can point out what I'm doing wrong that would be appreciated too.










share|improve this question













I need to setup a configuration file in Bash and believe Zenity is the best method but am having problems finding a link using google with a suitable example.



So far my code looks like this:



#!/bin/bash

zenity --forms --title="Laptop Adaptive Brightness" --text="Set Configuration"
--add-entry="/sys/class/backlight/??????/brightness"
--add-entry="Night time (min) value"
--add-entry="Day time (max) value"
--add-entry="Minutes after sunrise to max"
--add-entry="Minutes before sunset to min"

exit


and the resulting screen looks like this:



Adaptive Brightness Config



If values can't be preassigned to Zenity variables then I could put the current value into the field label ie:



   --add-entry="Night time (min) value (Current: $min)", 


And the user can leave the field blank to remain the same or enter a new value.



I'm still missing the best way of extracting Zenity fields to bash variables and writing them to the configuration file. Also I'm missing the code to read from configuration file to bash variables.



I'd appreciate a link to a Zenity example or a full answer would be even better. Thank you.



PS When I run the above script an error is reported when it completes:



$ adaptive-brightness-configGtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
||||


I'm a little confused by this and if you can point out what I'm doing wrong that would be appreciated too.







command-line bash scripts configuration zenity






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Feb 27 '17 at 0:17









WinEunuuchs2UnixWinEunuuchs2Unix

44.5k1079169




44.5k1079169








  • 4




    Probably you're overestimating Zenity's capabilities... I would make a simple GUI with Python (using Tk, GTK, Qt or whatever you want) instead of restricting myself to Bash+Zenity.
    – Byte Commander
    Feb 27 '17 at 0:35














  • 4




    Probably you're overestimating Zenity's capabilities... I would make a simple GUI with Python (using Tk, GTK, Qt or whatever you want) instead of restricting myself to Bash+Zenity.
    – Byte Commander
    Feb 27 '17 at 0:35








4




4




Probably you're overestimating Zenity's capabilities... I would make a simple GUI with Python (using Tk, GTK, Qt or whatever you want) instead of restricting myself to Bash+Zenity.
– Byte Commander
Feb 27 '17 at 0:35




Probably you're overestimating Zenity's capabilities... I would make a simple GUI with Python (using Tk, GTK, Qt or whatever you want) instead of restricting myself to Bash+Zenity.
– Byte Commander
Feb 27 '17 at 0:35










2 Answers
2






active

oldest

votes


















3














Zenity can only display previous value when there is only one entry field. As such the code below puts the previous values into the label fields and instructs user to type new value into entry fields or leave it blank to keep existing value.



The Bash Code





#!/bin/bash

# Read configuration file with entries separated by " " into array
IFS=' ' read -ra CfgArr < ~/bin/adaptive-brightness-configuration-file

# Zenity form with current values in entry label
# because initializing multiple entry data fields not supported
output=$(zenity --forms --title="Laptop Adaptive Brightness Configuration"
--text="Enter new settings or leave entries blank to keep (existing) settings"
--add-entry="/sys/class/backlight/??????/brightness driver : (${CfgArr[0]})"
--add-entry="Day time maximum display brightness : (${CfgArr[1]})"
--add-entry="Transition minutes after sunrise to maximum : (${CfgArr[2]})"
--add-entry="Night time minimum display brightness : (${CfgArr[3]})"
--add-entry="Transition minutes before sunset to minimum : (${CfgArr[4]})")

IFS='|' read -a ZenArr <<<$output # Split zenity entries separated by "|" into array elements

# Update non-blank zenity array entries into configuration array
for i in ${!ZenArr[@]}; do
if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]} ; fi
done

# write configuration file using array (fields automatically separated by " ")
echo "${CfgArr[@]}" > ~/bin/adaptive-brightness-configuration-file


I was surprised after hours of googling, examples of this code couldn't be found. Hopefully others googling the same problem can find this code.



The Screen



adaptive brightness 3



In this answer the zenity form has a different order and expanded labels for fields. Although 4882 is maximum for this intel_backlight driver it's like staring into the sun and 1000 is practical maximum indoors.



Many thanks to muru for guidance converting original code from old-style COBOL format using field names, to modern Bash format utilizing arrays.





Using yad instead of zenity



In 2018 I revamped the project and renamed it to Eyesome. Now it uses yad which is a super-charged forked version of zenity. yad uses the same coding style in bash and adds more functionality.



Notebook support for multiple tabs



Using yad you can display current field values plus create forms in tabbed notebook format:



eyesome-edit-configuration-general.png



Whilst writing this answer I noticed the screen was out of date and says 5 to 20 seconds. I've changed it to say 1 to 20 seconds for the next publication.



Monitor 3 from the tab list



Here is what Monitor 3 looks like from the tab list:



eyesome-edit-configuration-monitor-3.png



Sample code for generating this screen is listed in the next section.



Sample code



The three monitors share a common function to build the bulk of the code. For Monitor 3 we use:



# Monitor 3 notebook page
BuildMonitorPage "$CFG_MON3_NDX"
yad --plug=$KEY --tabnum=4 --form
"${aMonPage[@]}" > "$res4" &


The BuildMonitorPage function does the heavy lifting though. Here is what it looks like:



BuildMonitorPage () {
# Move configuration array monitor 1-3 to Working Screen fields
# $1 = CfgArr Starting Index Number

aMonPage=()
i="$1"
aMonPage+=("--field=Monitor Number::RO")
aMonPage+=("${CfgArr[$((i++))]}")

aMonPage+=("--field=Monitor Status::CB")
Status=("${CfgArr[$((i++))]}")
cbStatus="Enabled!Disabled"
cbStatus="${cbStatus/$Status/^$Status}"
aMonPage+=("$cbStatus")

aMonPage+=("--field=Monitor Type::CB")
Type=("${CfgArr[$((i++))]}")
cbType="Hardware!Software"
cbType="${cbType/$Type/^$Type}"
aMonPage+=("$cbType")

aMonPage+=("--field=Monitor Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Internal Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Xrandr Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Daytime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)
aMonPage+=("--field=Daytime Red::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Daytime Green::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Daytime Blue::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)
aMonPage+=("--field=Nighttime Red::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Green::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Blue::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Current Brightness::RO")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Current Gamma::RO")
aMonPage+=("${CfgArr[$((i++))]}")

} # BuildMonitorPage


Yad will store numbers internally to 6 decimal places by default. During presentation to user you can override the number of decimal places used. In the code above you see:



    aMonPage+=("--field=Nighttime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)


The last line contains current value from configuration array (CfgArr) followed by:





  • 0.1 minimum allowed value


  • 9999 maximum allowed value


  • .01 step value if user presses up arrow or down arrow to change


  • 2 number of decimal places displayed on screen


To see all the screens and read an overview see this Ask Ubuntu Answer:




  • Set initial startup background brightness depending on daytime


Visit the eyesome github page and download all the bash code here:





  • Set brightness and gamma for three monitors using sunrise and sunset times from internet






share|improve this answer



















  • 2




    Suggestions: use mapfile to read the contents of a file directly into an array. Use IFS='|' read -a fields <<<$output to get the contents of $output into an array, instead of repeatedly invoking awk.
    – muru
    Feb 27 '17 at 5:30












  • @muru your great suggestions have been implemented. Thanks for nudging me down the path to learning bash arrays :) The code is more concise now.
    – WinEunuuchs2Unix
    Feb 27 '17 at 7:25






  • 2




    Next, DRY: those ifs could be written: for i in ${!ZenArr[@]}; do if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]}; fi; done
    – muru
    Feb 27 '17 at 8:23












  • (There is a concise way to write that if condition: CfgArr[i]=${ZenArr[i]:-${CfgArr[i]}}, but it's rather ugly, IMO).
    – muru
    Feb 27 '17 at 8:26






  • 1




    Thanks, but you don't need to do that! :) One last thing: use "${CfgArr[@]}" , which expands to each array element as a separate argument, so echo "${CfgArr[@]}" will get you the same effect.
    – muru
    Feb 27 '17 at 11:46



















1














yad does the same a lot easier



$ yad --form                                                  
--field "/sys/class/backlight/??????/brightness driver" 10
--field "Day time maximum display brightness" 20
--field "Transition minutes after sunrise to maximum" 30 # And so go on


enter image description here






share|improve this answer























  • Thank you for mentioning yad. I use it most of the time now too. I'll update my answer with a sample.
    – WinEunuuchs2Unix
    Dec 26 '18 at 15:28











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "89"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f887669%2fusing-zenity-to-maintain-configuration-file%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









3














Zenity can only display previous value when there is only one entry field. As such the code below puts the previous values into the label fields and instructs user to type new value into entry fields or leave it blank to keep existing value.



The Bash Code





#!/bin/bash

# Read configuration file with entries separated by " " into array
IFS=' ' read -ra CfgArr < ~/bin/adaptive-brightness-configuration-file

# Zenity form with current values in entry label
# because initializing multiple entry data fields not supported
output=$(zenity --forms --title="Laptop Adaptive Brightness Configuration"
--text="Enter new settings or leave entries blank to keep (existing) settings"
--add-entry="/sys/class/backlight/??????/brightness driver : (${CfgArr[0]})"
--add-entry="Day time maximum display brightness : (${CfgArr[1]})"
--add-entry="Transition minutes after sunrise to maximum : (${CfgArr[2]})"
--add-entry="Night time minimum display brightness : (${CfgArr[3]})"
--add-entry="Transition minutes before sunset to minimum : (${CfgArr[4]})")

IFS='|' read -a ZenArr <<<$output # Split zenity entries separated by "|" into array elements

# Update non-blank zenity array entries into configuration array
for i in ${!ZenArr[@]}; do
if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]} ; fi
done

# write configuration file using array (fields automatically separated by " ")
echo "${CfgArr[@]}" > ~/bin/adaptive-brightness-configuration-file


I was surprised after hours of googling, examples of this code couldn't be found. Hopefully others googling the same problem can find this code.



The Screen



adaptive brightness 3



In this answer the zenity form has a different order and expanded labels for fields. Although 4882 is maximum for this intel_backlight driver it's like staring into the sun and 1000 is practical maximum indoors.



Many thanks to muru for guidance converting original code from old-style COBOL format using field names, to modern Bash format utilizing arrays.





Using yad instead of zenity



In 2018 I revamped the project and renamed it to Eyesome. Now it uses yad which is a super-charged forked version of zenity. yad uses the same coding style in bash and adds more functionality.



Notebook support for multiple tabs



Using yad you can display current field values plus create forms in tabbed notebook format:



eyesome-edit-configuration-general.png



Whilst writing this answer I noticed the screen was out of date and says 5 to 20 seconds. I've changed it to say 1 to 20 seconds for the next publication.



Monitor 3 from the tab list



Here is what Monitor 3 looks like from the tab list:



eyesome-edit-configuration-monitor-3.png



Sample code for generating this screen is listed in the next section.



Sample code



The three monitors share a common function to build the bulk of the code. For Monitor 3 we use:



# Monitor 3 notebook page
BuildMonitorPage "$CFG_MON3_NDX"
yad --plug=$KEY --tabnum=4 --form
"${aMonPage[@]}" > "$res4" &


The BuildMonitorPage function does the heavy lifting though. Here is what it looks like:



BuildMonitorPage () {
# Move configuration array monitor 1-3 to Working Screen fields
# $1 = CfgArr Starting Index Number

aMonPage=()
i="$1"
aMonPage+=("--field=Monitor Number::RO")
aMonPage+=("${CfgArr[$((i++))]}")

aMonPage+=("--field=Monitor Status::CB")
Status=("${CfgArr[$((i++))]}")
cbStatus="Enabled!Disabled"
cbStatus="${cbStatus/$Status/^$Status}"
aMonPage+=("$cbStatus")

aMonPage+=("--field=Monitor Type::CB")
Type=("${CfgArr[$((i++))]}")
cbType="Hardware!Software"
cbType="${cbType/$Type/^$Type}"
aMonPage+=("$cbType")

aMonPage+=("--field=Monitor Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Internal Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Xrandr Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Daytime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)
aMonPage+=("--field=Daytime Red::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Daytime Green::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Daytime Blue::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)
aMonPage+=("--field=Nighttime Red::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Green::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Blue::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Current Brightness::RO")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Current Gamma::RO")
aMonPage+=("${CfgArr[$((i++))]}")

} # BuildMonitorPage


Yad will store numbers internally to 6 decimal places by default. During presentation to user you can override the number of decimal places used. In the code above you see:



    aMonPage+=("--field=Nighttime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)


The last line contains current value from configuration array (CfgArr) followed by:





  • 0.1 minimum allowed value


  • 9999 maximum allowed value


  • .01 step value if user presses up arrow or down arrow to change


  • 2 number of decimal places displayed on screen


To see all the screens and read an overview see this Ask Ubuntu Answer:




  • Set initial startup background brightness depending on daytime


Visit the eyesome github page and download all the bash code here:





  • Set brightness and gamma for three monitors using sunrise and sunset times from internet






share|improve this answer



















  • 2




    Suggestions: use mapfile to read the contents of a file directly into an array. Use IFS='|' read -a fields <<<$output to get the contents of $output into an array, instead of repeatedly invoking awk.
    – muru
    Feb 27 '17 at 5:30












  • @muru your great suggestions have been implemented. Thanks for nudging me down the path to learning bash arrays :) The code is more concise now.
    – WinEunuuchs2Unix
    Feb 27 '17 at 7:25






  • 2




    Next, DRY: those ifs could be written: for i in ${!ZenArr[@]}; do if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]}; fi; done
    – muru
    Feb 27 '17 at 8:23












  • (There is a concise way to write that if condition: CfgArr[i]=${ZenArr[i]:-${CfgArr[i]}}, but it's rather ugly, IMO).
    – muru
    Feb 27 '17 at 8:26






  • 1




    Thanks, but you don't need to do that! :) One last thing: use "${CfgArr[@]}" , which expands to each array element as a separate argument, so echo "${CfgArr[@]}" will get you the same effect.
    – muru
    Feb 27 '17 at 11:46
















3














Zenity can only display previous value when there is only one entry field. As such the code below puts the previous values into the label fields and instructs user to type new value into entry fields or leave it blank to keep existing value.



The Bash Code





#!/bin/bash

# Read configuration file with entries separated by " " into array
IFS=' ' read -ra CfgArr < ~/bin/adaptive-brightness-configuration-file

# Zenity form with current values in entry label
# because initializing multiple entry data fields not supported
output=$(zenity --forms --title="Laptop Adaptive Brightness Configuration"
--text="Enter new settings or leave entries blank to keep (existing) settings"
--add-entry="/sys/class/backlight/??????/brightness driver : (${CfgArr[0]})"
--add-entry="Day time maximum display brightness : (${CfgArr[1]})"
--add-entry="Transition minutes after sunrise to maximum : (${CfgArr[2]})"
--add-entry="Night time minimum display brightness : (${CfgArr[3]})"
--add-entry="Transition minutes before sunset to minimum : (${CfgArr[4]})")

IFS='|' read -a ZenArr <<<$output # Split zenity entries separated by "|" into array elements

# Update non-blank zenity array entries into configuration array
for i in ${!ZenArr[@]}; do
if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]} ; fi
done

# write configuration file using array (fields automatically separated by " ")
echo "${CfgArr[@]}" > ~/bin/adaptive-brightness-configuration-file


I was surprised after hours of googling, examples of this code couldn't be found. Hopefully others googling the same problem can find this code.



The Screen



adaptive brightness 3



In this answer the zenity form has a different order and expanded labels for fields. Although 4882 is maximum for this intel_backlight driver it's like staring into the sun and 1000 is practical maximum indoors.



Many thanks to muru for guidance converting original code from old-style COBOL format using field names, to modern Bash format utilizing arrays.





Using yad instead of zenity



In 2018 I revamped the project and renamed it to Eyesome. Now it uses yad which is a super-charged forked version of zenity. yad uses the same coding style in bash and adds more functionality.



Notebook support for multiple tabs



Using yad you can display current field values plus create forms in tabbed notebook format:



eyesome-edit-configuration-general.png



Whilst writing this answer I noticed the screen was out of date and says 5 to 20 seconds. I've changed it to say 1 to 20 seconds for the next publication.



Monitor 3 from the tab list



Here is what Monitor 3 looks like from the tab list:



eyesome-edit-configuration-monitor-3.png



Sample code for generating this screen is listed in the next section.



Sample code



The three monitors share a common function to build the bulk of the code. For Monitor 3 we use:



# Monitor 3 notebook page
BuildMonitorPage "$CFG_MON3_NDX"
yad --plug=$KEY --tabnum=4 --form
"${aMonPage[@]}" > "$res4" &


The BuildMonitorPage function does the heavy lifting though. Here is what it looks like:



BuildMonitorPage () {
# Move configuration array monitor 1-3 to Working Screen fields
# $1 = CfgArr Starting Index Number

aMonPage=()
i="$1"
aMonPage+=("--field=Monitor Number::RO")
aMonPage+=("${CfgArr[$((i++))]}")

aMonPage+=("--field=Monitor Status::CB")
Status=("${CfgArr[$((i++))]}")
cbStatus="Enabled!Disabled"
cbStatus="${cbStatus/$Status/^$Status}"
aMonPage+=("$cbStatus")

aMonPage+=("--field=Monitor Type::CB")
Type=("${CfgArr[$((i++))]}")
cbType="Hardware!Software"
cbType="${cbType/$Type/^$Type}"
aMonPage+=("$cbType")

aMonPage+=("--field=Monitor Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Internal Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Xrandr Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Daytime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)
aMonPage+=("--field=Daytime Red::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Daytime Green::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Daytime Blue::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)
aMonPage+=("--field=Nighttime Red::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Green::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Blue::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Current Brightness::RO")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Current Gamma::RO")
aMonPage+=("${CfgArr[$((i++))]}")

} # BuildMonitorPage


Yad will store numbers internally to 6 decimal places by default. During presentation to user you can override the number of decimal places used. In the code above you see:



    aMonPage+=("--field=Nighttime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)


The last line contains current value from configuration array (CfgArr) followed by:





  • 0.1 minimum allowed value


  • 9999 maximum allowed value


  • .01 step value if user presses up arrow or down arrow to change


  • 2 number of decimal places displayed on screen


To see all the screens and read an overview see this Ask Ubuntu Answer:




  • Set initial startup background brightness depending on daytime


Visit the eyesome github page and download all the bash code here:





  • Set brightness and gamma for three monitors using sunrise and sunset times from internet






share|improve this answer



















  • 2




    Suggestions: use mapfile to read the contents of a file directly into an array. Use IFS='|' read -a fields <<<$output to get the contents of $output into an array, instead of repeatedly invoking awk.
    – muru
    Feb 27 '17 at 5:30












  • @muru your great suggestions have been implemented. Thanks for nudging me down the path to learning bash arrays :) The code is more concise now.
    – WinEunuuchs2Unix
    Feb 27 '17 at 7:25






  • 2




    Next, DRY: those ifs could be written: for i in ${!ZenArr[@]}; do if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]}; fi; done
    – muru
    Feb 27 '17 at 8:23












  • (There is a concise way to write that if condition: CfgArr[i]=${ZenArr[i]:-${CfgArr[i]}}, but it's rather ugly, IMO).
    – muru
    Feb 27 '17 at 8:26






  • 1




    Thanks, but you don't need to do that! :) One last thing: use "${CfgArr[@]}" , which expands to each array element as a separate argument, so echo "${CfgArr[@]}" will get you the same effect.
    – muru
    Feb 27 '17 at 11:46














3












3








3






Zenity can only display previous value when there is only one entry field. As such the code below puts the previous values into the label fields and instructs user to type new value into entry fields or leave it blank to keep existing value.



The Bash Code





#!/bin/bash

# Read configuration file with entries separated by " " into array
IFS=' ' read -ra CfgArr < ~/bin/adaptive-brightness-configuration-file

# Zenity form with current values in entry label
# because initializing multiple entry data fields not supported
output=$(zenity --forms --title="Laptop Adaptive Brightness Configuration"
--text="Enter new settings or leave entries blank to keep (existing) settings"
--add-entry="/sys/class/backlight/??????/brightness driver : (${CfgArr[0]})"
--add-entry="Day time maximum display brightness : (${CfgArr[1]})"
--add-entry="Transition minutes after sunrise to maximum : (${CfgArr[2]})"
--add-entry="Night time minimum display brightness : (${CfgArr[3]})"
--add-entry="Transition minutes before sunset to minimum : (${CfgArr[4]})")

IFS='|' read -a ZenArr <<<$output # Split zenity entries separated by "|" into array elements

# Update non-blank zenity array entries into configuration array
for i in ${!ZenArr[@]}; do
if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]} ; fi
done

# write configuration file using array (fields automatically separated by " ")
echo "${CfgArr[@]}" > ~/bin/adaptive-brightness-configuration-file


I was surprised after hours of googling, examples of this code couldn't be found. Hopefully others googling the same problem can find this code.



The Screen



adaptive brightness 3



In this answer the zenity form has a different order and expanded labels for fields. Although 4882 is maximum for this intel_backlight driver it's like staring into the sun and 1000 is practical maximum indoors.



Many thanks to muru for guidance converting original code from old-style COBOL format using field names, to modern Bash format utilizing arrays.





Using yad instead of zenity



In 2018 I revamped the project and renamed it to Eyesome. Now it uses yad which is a super-charged forked version of zenity. yad uses the same coding style in bash and adds more functionality.



Notebook support for multiple tabs



Using yad you can display current field values plus create forms in tabbed notebook format:



eyesome-edit-configuration-general.png



Whilst writing this answer I noticed the screen was out of date and says 5 to 20 seconds. I've changed it to say 1 to 20 seconds for the next publication.



Monitor 3 from the tab list



Here is what Monitor 3 looks like from the tab list:



eyesome-edit-configuration-monitor-3.png



Sample code for generating this screen is listed in the next section.



Sample code



The three monitors share a common function to build the bulk of the code. For Monitor 3 we use:



# Monitor 3 notebook page
BuildMonitorPage "$CFG_MON3_NDX"
yad --plug=$KEY --tabnum=4 --form
"${aMonPage[@]}" > "$res4" &


The BuildMonitorPage function does the heavy lifting though. Here is what it looks like:



BuildMonitorPage () {
# Move configuration array monitor 1-3 to Working Screen fields
# $1 = CfgArr Starting Index Number

aMonPage=()
i="$1"
aMonPage+=("--field=Monitor Number::RO")
aMonPage+=("${CfgArr[$((i++))]}")

aMonPage+=("--field=Monitor Status::CB")
Status=("${CfgArr[$((i++))]}")
cbStatus="Enabled!Disabled"
cbStatus="${cbStatus/$Status/^$Status}"
aMonPage+=("$cbStatus")

aMonPage+=("--field=Monitor Type::CB")
Type=("${CfgArr[$((i++))]}")
cbType="Hardware!Software"
cbType="${cbType/$Type/^$Type}"
aMonPage+=("$cbType")

aMonPage+=("--field=Monitor Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Internal Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Xrandr Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Daytime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)
aMonPage+=("--field=Daytime Red::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Daytime Green::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Daytime Blue::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)
aMonPage+=("--field=Nighttime Red::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Green::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Blue::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Current Brightness::RO")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Current Gamma::RO")
aMonPage+=("${CfgArr[$((i++))]}")

} # BuildMonitorPage


Yad will store numbers internally to 6 decimal places by default. During presentation to user you can override the number of decimal places used. In the code above you see:



    aMonPage+=("--field=Nighttime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)


The last line contains current value from configuration array (CfgArr) followed by:





  • 0.1 minimum allowed value


  • 9999 maximum allowed value


  • .01 step value if user presses up arrow or down arrow to change


  • 2 number of decimal places displayed on screen


To see all the screens and read an overview see this Ask Ubuntu Answer:




  • Set initial startup background brightness depending on daytime


Visit the eyesome github page and download all the bash code here:





  • Set brightness and gamma for three monitors using sunrise and sunset times from internet






share|improve this answer














Zenity can only display previous value when there is only one entry field. As such the code below puts the previous values into the label fields and instructs user to type new value into entry fields or leave it blank to keep existing value.



The Bash Code





#!/bin/bash

# Read configuration file with entries separated by " " into array
IFS=' ' read -ra CfgArr < ~/bin/adaptive-brightness-configuration-file

# Zenity form with current values in entry label
# because initializing multiple entry data fields not supported
output=$(zenity --forms --title="Laptop Adaptive Brightness Configuration"
--text="Enter new settings or leave entries blank to keep (existing) settings"
--add-entry="/sys/class/backlight/??????/brightness driver : (${CfgArr[0]})"
--add-entry="Day time maximum display brightness : (${CfgArr[1]})"
--add-entry="Transition minutes after sunrise to maximum : (${CfgArr[2]})"
--add-entry="Night time minimum display brightness : (${CfgArr[3]})"
--add-entry="Transition minutes before sunset to minimum : (${CfgArr[4]})")

IFS='|' read -a ZenArr <<<$output # Split zenity entries separated by "|" into array elements

# Update non-blank zenity array entries into configuration array
for i in ${!ZenArr[@]}; do
if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]} ; fi
done

# write configuration file using array (fields automatically separated by " ")
echo "${CfgArr[@]}" > ~/bin/adaptive-brightness-configuration-file


I was surprised after hours of googling, examples of this code couldn't be found. Hopefully others googling the same problem can find this code.



The Screen



adaptive brightness 3



In this answer the zenity form has a different order and expanded labels for fields. Although 4882 is maximum for this intel_backlight driver it's like staring into the sun and 1000 is practical maximum indoors.



Many thanks to muru for guidance converting original code from old-style COBOL format using field names, to modern Bash format utilizing arrays.





Using yad instead of zenity



In 2018 I revamped the project and renamed it to Eyesome. Now it uses yad which is a super-charged forked version of zenity. yad uses the same coding style in bash and adds more functionality.



Notebook support for multiple tabs



Using yad you can display current field values plus create forms in tabbed notebook format:



eyesome-edit-configuration-general.png



Whilst writing this answer I noticed the screen was out of date and says 5 to 20 seconds. I've changed it to say 1 to 20 seconds for the next publication.



Monitor 3 from the tab list



Here is what Monitor 3 looks like from the tab list:



eyesome-edit-configuration-monitor-3.png



Sample code for generating this screen is listed in the next section.



Sample code



The three monitors share a common function to build the bulk of the code. For Monitor 3 we use:



# Monitor 3 notebook page
BuildMonitorPage "$CFG_MON3_NDX"
yad --plug=$KEY --tabnum=4 --form
"${aMonPage[@]}" > "$res4" &


The BuildMonitorPage function does the heavy lifting though. Here is what it looks like:



BuildMonitorPage () {
# Move configuration array monitor 1-3 to Working Screen fields
# $1 = CfgArr Starting Index Number

aMonPage=()
i="$1"
aMonPage+=("--field=Monitor Number::RO")
aMonPage+=("${CfgArr[$((i++))]}")

aMonPage+=("--field=Monitor Status::CB")
Status=("${CfgArr[$((i++))]}")
cbStatus="Enabled!Disabled"
cbStatus="${cbStatus/$Status/^$Status}"
aMonPage+=("$cbStatus")

aMonPage+=("--field=Monitor Type::CB")
Type=("${CfgArr[$((i++))]}")
cbType="Hardware!Software"
cbType="${cbType/$Type/^$Type}"
aMonPage+=("$cbType")

aMonPage+=("--field=Monitor Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Internal Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Xrandr Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Daytime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)
aMonPage+=("--field=Daytime Red::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Daytime Green::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Daytime Blue::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)
aMonPage+=("--field=Nighttime Red::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Green::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Blue::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Current Brightness::RO")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Current Gamma::RO")
aMonPage+=("${CfgArr[$((i++))]}")

} # BuildMonitorPage


Yad will store numbers internally to 6 decimal places by default. During presentation to user you can override the number of decimal places used. In the code above you see:



    aMonPage+=("--field=Nighttime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)


The last line contains current value from configuration array (CfgArr) followed by:





  • 0.1 minimum allowed value


  • 9999 maximum allowed value


  • .01 step value if user presses up arrow or down arrow to change


  • 2 number of decimal places displayed on screen


To see all the screens and read an overview see this Ask Ubuntu Answer:




  • Set initial startup background brightness depending on daytime


Visit the eyesome github page and download all the bash code here:





  • Set brightness and gamma for three monitors using sunrise and sunset times from internet







share|improve this answer














share|improve this answer



share|improve this answer








edited Dec 26 '18 at 16:12

























answered Feb 27 '17 at 5:05









WinEunuuchs2UnixWinEunuuchs2Unix

44.5k1079169




44.5k1079169








  • 2




    Suggestions: use mapfile to read the contents of a file directly into an array. Use IFS='|' read -a fields <<<$output to get the contents of $output into an array, instead of repeatedly invoking awk.
    – muru
    Feb 27 '17 at 5:30












  • @muru your great suggestions have been implemented. Thanks for nudging me down the path to learning bash arrays :) The code is more concise now.
    – WinEunuuchs2Unix
    Feb 27 '17 at 7:25






  • 2




    Next, DRY: those ifs could be written: for i in ${!ZenArr[@]}; do if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]}; fi; done
    – muru
    Feb 27 '17 at 8:23












  • (There is a concise way to write that if condition: CfgArr[i]=${ZenArr[i]:-${CfgArr[i]}}, but it's rather ugly, IMO).
    – muru
    Feb 27 '17 at 8:26






  • 1




    Thanks, but you don't need to do that! :) One last thing: use "${CfgArr[@]}" , which expands to each array element as a separate argument, so echo "${CfgArr[@]}" will get you the same effect.
    – muru
    Feb 27 '17 at 11:46














  • 2




    Suggestions: use mapfile to read the contents of a file directly into an array. Use IFS='|' read -a fields <<<$output to get the contents of $output into an array, instead of repeatedly invoking awk.
    – muru
    Feb 27 '17 at 5:30












  • @muru your great suggestions have been implemented. Thanks for nudging me down the path to learning bash arrays :) The code is more concise now.
    – WinEunuuchs2Unix
    Feb 27 '17 at 7:25






  • 2




    Next, DRY: those ifs could be written: for i in ${!ZenArr[@]}; do if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]}; fi; done
    – muru
    Feb 27 '17 at 8:23












  • (There is a concise way to write that if condition: CfgArr[i]=${ZenArr[i]:-${CfgArr[i]}}, but it's rather ugly, IMO).
    – muru
    Feb 27 '17 at 8:26






  • 1




    Thanks, but you don't need to do that! :) One last thing: use "${CfgArr[@]}" , which expands to each array element as a separate argument, so echo "${CfgArr[@]}" will get you the same effect.
    – muru
    Feb 27 '17 at 11:46








2




2




Suggestions: use mapfile to read the contents of a file directly into an array. Use IFS='|' read -a fields <<<$output to get the contents of $output into an array, instead of repeatedly invoking awk.
– muru
Feb 27 '17 at 5:30






Suggestions: use mapfile to read the contents of a file directly into an array. Use IFS='|' read -a fields <<<$output to get the contents of $output into an array, instead of repeatedly invoking awk.
– muru
Feb 27 '17 at 5:30














@muru your great suggestions have been implemented. Thanks for nudging me down the path to learning bash arrays :) The code is more concise now.
– WinEunuuchs2Unix
Feb 27 '17 at 7:25




@muru your great suggestions have been implemented. Thanks for nudging me down the path to learning bash arrays :) The code is more concise now.
– WinEunuuchs2Unix
Feb 27 '17 at 7:25




2




2




Next, DRY: those ifs could be written: for i in ${!ZenArr[@]}; do if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]}; fi; done
– muru
Feb 27 '17 at 8:23






Next, DRY: those ifs could be written: for i in ${!ZenArr[@]}; do if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]}; fi; done
– muru
Feb 27 '17 at 8:23














(There is a concise way to write that if condition: CfgArr[i]=${ZenArr[i]:-${CfgArr[i]}}, but it's rather ugly, IMO).
– muru
Feb 27 '17 at 8:26




(There is a concise way to write that if condition: CfgArr[i]=${ZenArr[i]:-${CfgArr[i]}}, but it's rather ugly, IMO).
– muru
Feb 27 '17 at 8:26




1




1




Thanks, but you don't need to do that! :) One last thing: use "${CfgArr[@]}" , which expands to each array element as a separate argument, so echo "${CfgArr[@]}" will get you the same effect.
– muru
Feb 27 '17 at 11:46




Thanks, but you don't need to do that! :) One last thing: use "${CfgArr[@]}" , which expands to each array element as a separate argument, so echo "${CfgArr[@]}" will get you the same effect.
– muru
Feb 27 '17 at 11:46













1














yad does the same a lot easier



$ yad --form                                                  
--field "/sys/class/backlight/??????/brightness driver" 10
--field "Day time maximum display brightness" 20
--field "Transition minutes after sunrise to maximum" 30 # And so go on


enter image description here






share|improve this answer























  • Thank you for mentioning yad. I use it most of the time now too. I'll update my answer with a sample.
    – WinEunuuchs2Unix
    Dec 26 '18 at 15:28
















1














yad does the same a lot easier



$ yad --form                                                  
--field "/sys/class/backlight/??????/brightness driver" 10
--field "Day time maximum display brightness" 20
--field "Transition minutes after sunrise to maximum" 30 # And so go on


enter image description here






share|improve this answer























  • Thank you for mentioning yad. I use it most of the time now too. I'll update my answer with a sample.
    – WinEunuuchs2Unix
    Dec 26 '18 at 15:28














1












1








1






yad does the same a lot easier



$ yad --form                                                  
--field "/sys/class/backlight/??????/brightness driver" 10
--field "Day time maximum display brightness" 20
--field "Transition minutes after sunrise to maximum" 30 # And so go on


enter image description here






share|improve this answer














yad does the same a lot easier



$ yad --form                                                  
--field "/sys/class/backlight/??????/brightness driver" 10
--field "Day time maximum display brightness" 20
--field "Transition minutes after sunrise to maximum" 30 # And so go on


enter image description here







share|improve this answer














share|improve this answer



share|improve this answer








edited Dec 26 '18 at 14:22









Sergiy Kolodyazhnyy

70.3k9146307




70.3k9146307










answered Dec 26 '18 at 14:04









Julio NJulio N

111




111












  • Thank you for mentioning yad. I use it most of the time now too. I'll update my answer with a sample.
    – WinEunuuchs2Unix
    Dec 26 '18 at 15:28


















  • Thank you for mentioning yad. I use it most of the time now too. I'll update my answer with a sample.
    – WinEunuuchs2Unix
    Dec 26 '18 at 15:28
















Thank you for mentioning yad. I use it most of the time now too. I'll update my answer with a sample.
– WinEunuuchs2Unix
Dec 26 '18 at 15:28




Thank you for mentioning yad. I use it most of the time now too. I'll update my answer with a sample.
– WinEunuuchs2Unix
Dec 26 '18 at 15:28


















draft saved

draft discarded




















































Thanks for contributing an answer to Ask Ubuntu!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f887669%2fusing-zenity-to-maintain-configuration-file%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror

Mangá

 ⁒  ․,‪⁊‑⁙ ⁖, ⁇‒※‌, †,⁖‗‌⁝    ‾‸⁘,‖⁔⁣,⁂‾
”‑,‥–,‬ ,⁀‹⁋‴⁑ ‒ ,‴⁋”‼ ⁨,‷⁔„ ‰′,‐‚ ‥‡‎“‷⁃⁨⁅⁣,⁔
⁇‘⁔⁡⁏⁌⁡‿‶‏⁨ ⁣⁕⁖⁨⁩⁥‽⁀  ‴‬⁜‟ ⁃‣‧⁕‮ …‍⁨‴ ⁩,⁚⁖‫ ,‵ ⁀,‮⁝‣‣ ⁑  ⁂– ․, ‾‽ ‏⁁“⁗‸ ‾… ‹‡⁌⁎‸‘ ‡⁏⁌‪ ‵⁛ ‎⁨ ―⁦⁤⁄⁕