Cocoa Dialog display command output and also write to log file

May
Contributor III

Hi all

I'm jumping into Cocoa Dialog and have modified an example from @mm2270 , thanks!,
i'd like to be able to display all of the output from softwareupdate -i in the Cocoa Dialog window but also write that info to a log file (which is later used to check success, if a restart is required and also so i have a record).

here's what i'm testing with, if i add >> "$logpath" then the log file gets written to but Cocoa Dialog doesn't display the output fully, any advise is appreciated!

cdPath="/Applications/Utilities/CocoaDialog.app/Contents/MacOS/CocoaDialog"

## Create the name pipe input for the progressbar
rm -f /tmp/hpipe
mkfifo /tmp/hpipe
sleep 0.2

## Display indeterminate progress bar
echo "Displaying progress bar window."
"$cdPath" progressbar --indeterminate --title "Installing Apple Updates" --text "Progress..." 
--posX "right" --posY "top" --width 225 --float --icon info < /tmp/hpipe &

## Send progress through the named pipe
exec 3<> /tmp/hpipe

softwareupdate -i "$Install" | while read line; do

    outPut=$( echo "$line" )
       echo "$outPut" >&3    #displays output properly
       #echo "$outPut" >&3 >> "$logpath"   # writes to log file as needed but not displaying text

done

## Wait 1 second before shutting off progressbar
sleep 1

# Turn off progress bar by closing file descriptor 3 and removing the named pipe
echo "Closing progress bar."
exec 3>&-
rm -f /tmp/hpipe
1 ACCEPTED SOLUTION

mm2270
Legendary Contributor III

@May Inside the while read loop, you can do as many actions as you want, technically speaking. Just send the line info to the log file, and then on a separate line, send the "$line" to the file descriptor for cocoadialog to use.

Here's a modified version of the script above. I don't know if what you posted was only a snippet, but I didn't see a place where you specified or created the log file, so adjust what I have accordingly.

#!/bin/bash

cdPath="/Applications/Utilities/CocoaDialog.app/Contents/MacOS/CocoaDialog"

logpath="/Library/Logs/testlog.log"  ## Specifies the path to the log

## Create the log file if it's not already there
if [ ! -e "$logpath" ]; then
    touch "$logpath"
fi

## Create the name pipe input for the progressbar
rm -f /tmp/hpipe
mkfifo /tmp/hpipe
sleep 0.2

## Display indeterminate progress bar
echo "Displaying progress bar window."
"$cdPath" progressbar --indeterminate --title "Installing Apple Updates" --text "Progress..." 
--posX "right" --posY "top" --width 225 --float --icon info < /tmp/hpipe &

## Send progress through the named pipe
exec 3<> /tmp/hpipe

softwareupdate -i "$Install" | while read line; do  ## Assuming you have the $install variable specified elsewhere in the script
    echo "$line" >> "$logpath" ## We send the "line" to the log file here
    echo "10 $line" >&3    ## We send the same "line" to the file descriptor, which cocoadialog reads back
done

## Wait 1 second before shutting off progressbar
sleep 1

# Turn off progress bar by closing file descriptor 3 and removing the named pipe
echo "Closing progress bar."
exec 3>&-
rm -f /tmp/hpipe

Hope that helps.

View solution in original post

7 REPLIES 7

alexjdale
Valued Contributor III

You didn't declare the logpath variable?

mm2270
Legendary Contributor III

@May Inside the while read loop, you can do as many actions as you want, technically speaking. Just send the line info to the log file, and then on a separate line, send the "$line" to the file descriptor for cocoadialog to use.

Here's a modified version of the script above. I don't know if what you posted was only a snippet, but I didn't see a place where you specified or created the log file, so adjust what I have accordingly.

#!/bin/bash

cdPath="/Applications/Utilities/CocoaDialog.app/Contents/MacOS/CocoaDialog"

logpath="/Library/Logs/testlog.log"  ## Specifies the path to the log

## Create the log file if it's not already there
if [ ! -e "$logpath" ]; then
    touch "$logpath"
fi

## Create the name pipe input for the progressbar
rm -f /tmp/hpipe
mkfifo /tmp/hpipe
sleep 0.2

## Display indeterminate progress bar
echo "Displaying progress bar window."
"$cdPath" progressbar --indeterminate --title "Installing Apple Updates" --text "Progress..." 
--posX "right" --posY "top" --width 225 --float --icon info < /tmp/hpipe &

## Send progress through the named pipe
exec 3<> /tmp/hpipe

softwareupdate -i "$Install" | while read line; do  ## Assuming you have the $install variable specified elsewhere in the script
    echo "$line" >> "$logpath" ## We send the "line" to the log file here
    echo "10 $line" >&3    ## We send the same "line" to the file descriptor, which cocoadialog reads back
done

## Wait 1 second before shutting off progressbar
sleep 1

# Turn off progress bar by closing file descriptor 3 and removing the named pipe
echo "Closing progress bar."
exec 3>&-
rm -f /tmp/hpipe

Hope that helps.

May
Contributor III

Awesome, thank you @mm2270

that makes sense, i hadn't fully grasped how how it was functioning, now i can do all the good stuff!.
(it's just a snippet, $logpath and $install are set earlier in the full script,)

May
Contributor III

@mm2270

one question please, what's the function of the 10 in

echo "10 $line" >&3

alexjdale
Valued Contributor III

CocoaDialog needs a number at the start of input to a progress bar. With a regular progress bar, that number between 1 and 100 indicates the percentage of the bar it would display as filled.

With an indeterminate progress bar that is always filled, it doesn't matter what number you pass, it's just a requirement.

mm2270
Legendary Contributor III

@May, @alexjdale is correct. In order to make the progress bar update it's text, it needs an integer value before the text you want it to display, otherwise it won't get updated and will just display the initial text you started the progress bar window with.

May
Contributor III

@alexjdale @mm2270 Thank you