3

I have a bash script which makes some system changes involving a list of URL addresses beginning with "http", and I'm trying to write a GUI for it.

I'm stuck with the following last part:


changes="$(cat /home/$USER/.updates.log | grep http)"
if [ "$changes" != 0 ]; then
    zenity --question --text "Changes found in:\n$changes\n\nWould you like to update now?"
        if [ $? = 0 ]
        then
# password
sudo_password="$(gksudo --print-pass --description 'MyScript' -- : 2>/dev/null)"
# check for null entry or cancellation
if [[ ${?} != 0 || -z ${sudo_password} ]]
then
    exit 4
fi
if ! sudo -kSp '' [ 1 ] <<<"${sudo_password}" 2>/dev/null
then
    exit 4
fi
# notify
notify-send "Applying updates..." -i gtk-dialog-info -t 1000 -u normal &
# proceed to update
cuser="${SUDO_USER:-$USER}"
sudo -Sp ''  sudo /usr/local/bin/MyScript <<<"${sudo_password}"
# option to view log
new_update="$(cat /home/$USER/.updates.log | grep 'MyScript completed at ' | awk -F ' at ' '{print $2}')"
zenity --question --text "MyScript updated at $new_update\n\nWould you like to view the log file now?"
if [ $? = 0 ]
then
# display log
    zenity --text-info --filename=/home/$USER/.updates.log --width 680 --height 680
fi
fi
fi

Actually, it seems the tricky part for me is here:

if [ "$changes" != 0 ]; then

I want to simply display a message like "No updates found; exiting..." if that file contains no lines beginning with "http" but this simply creates a blank line in the zenity question dialog box. It seems I need to modify this line, and also add another command under "else" but I just don't know how and where...

2
  • 2
    You'll have more luck by reducing your script to the parts relevant to the actual problem. And provide a complete script (including shebang). Not many people enjoy debugging dozens of lines of badly written shell script snippets. Aften that you should clarify your question (if it hasn't been solved in the process already).
    – Marco
    Oct 6, 2015 at 10:57
  • 1
    Why do you have a ; after your if statement? you only need it if the then part follows in the same line, in different lines you don't need that.
    – YoMismo
    Oct 6, 2015 at 11:40

2 Answers 2

2

I can't test the rest of your script since I don't have the necessary data and don't even know what it does but this line is certainly wrong:

changes="$(cat /home/$USER/.updates.log | grep http)"

That will save the output of your grep command in $changes, not the number of times the string was found, but the actual lines returned. For example:

$ cat file 
one http
two http
three http
$ changes=$(cat file | grep http)
$ echo "$changes" 
one http two http three http

As you can see above, $changes is just each matching line from the file concatenated into a single variable. What you wanted was something like (no need for cat, by the way, grep can take a filename as input):

$ changes=$(grep -c http file)
$ echo $changes 
3

The -c switch makes grep print the number of matching lines instead of the lines themselves. Alternatively, you can pass the output through wc -l to count the lines:

changes=$(grep http file | wc -l)

Either one will do and you will now be able to check whether $changes is greater than 0:

if [ "$changes" -gt 0 ]]; then 
        ...
fi

If you want to display the changes, use your original approach but don't compare it to 0. Instead, use -z to check whether the variable is empty:

changes=$(grep http /home/$USER/.updates.log)
## If $changes is empty
if [ -z "$changes" ]
then
     notify-send "Found no updates; exiting..." -i gtk-dialog-info -t 1000 -u normal &
     exit
else
     zenity --question --text "Changes found in:\n$changes\n\nWould you like to update now?"
    ...
fi
3
  • Or exactly use exit status of grep itself if grep -q http /home/$USER/.updates.log 2>/dev/null
    – Costas
    Oct 6, 2015 at 12:02
  • Thanks a lot! Actually the last and shorter part of your answer is what I want, because I'll use the whole list of URL addresses if changes are found, while simply quitting the script when there are no changes/updates. Therefore it would be easier, I think, to modify the "if" statement to allow me to quit in that case (i.e. "If $changes is empty") and to follow the other options after "else"...
    – Sadi
    Oct 6, 2015 at 12:21
  • Checked this, and it's working perfectly! I'll do the editing and accept your answer. THX!
    – Sadi
    Oct 6, 2015 at 12:44
0

About the problem WHERE to put the rest of the condition, the hint is to always respect the indentation, it surely make easier the task : )

I've not tested it (I could be wrong), but I would try something like this for begin:

changes="$(cat /home/$USER/.updates.log | grep http)"
if [ "$changes" != 0 ]; then
  zenity --question --text "Changes found in:\n<i>$changes</i>\n\nWould you like to update now?"
  if [ $? = 0 ]; then
    ## password
    sudo_password="$(gksudo --print-pass --description 'MyScript' -- : 2>/dev/null)"
    ## check for null entry or cancellation
    if [[ ${?} != 0 || -z ${sudo_password} ]]; then
      exit 4
    fi
    if ! sudo -kSp '' [ 1 ] <<<"${sudo_password}" 2>/dev/null; then
      exit 4
    fi
    ## notify
    notify-send "Applying updates..." -i gtk-dialog-info -t 1000 -u normal &
    ## proceed to update
    cuser="${SUDO_USER:-$USER}"
    sudo -Sp ''  sudo /usr/local/bin/MyScript <<<"${sudo_password}"
    ## option to view log
    new_update="$(cat /home/$USER/.updates.log | grep 'MyScript completed at ' | awk -F ' at ' '{print $2}')"
    zenity --question --text "MyScript updated at <b><i>$new_update</i></b>\n  \nWould you like to view the log file now?"
    if [ $? = 0 ]; then
      ## display log
      zenity --text-info --filename=/home/$USER/.updates.log --width 680 --height 680
    fi
  fi
## Here is where you can choose what to do if there are no results
else
  zenity --text-info "No updates found; exiting..." 
fi
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .