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
    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 '15 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 '15 at 11:40
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
  • Or exactly use exit status of grep itself if grep -q http /home/$USER/.updates.log 2>/dev/null – Costas Oct 6 '15 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 '15 at 12:21
  • Checked this, and it's working perfectly! I'll do the editing and accept your answer. THX! – Sadi Oct 6 '15 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
  • You're not fixing the main problem which is that the OP is attempting to compare a string to 0. In fact, as far as I can tell, you're not fixing any problem at all apart from indentation. This will not work any better than what the OP has posted. – terdon Oct 6 '15 at 11:16
  • Reading the question what I understood was that his main problem was to understand where to put the else condition. That's why I answered this way. To help him to find the solution. Not for solve his problem and put it on a silver plate. – lese Oct 6 '15 at 12:30
  • Ah, yes, you've added the else (that's not easy to spot by the way), fair enough. Still, the main question is about the if [ "$changes" != 0 ]; then bit. – terdon Oct 6 '15 at 12:38
  • yeah man you are the best! XD – lese Oct 6 '15 at 12:40
  • Thank you for the formatting guide, you see, I'm still learning ;-) – Sadi Oct 6 '15 at 12:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.