When we run a command that takes a while such as source compile or brew upgrade, we usually do other things such as web searching rather than watching the command running the whole time.

Is there any possible way that I can get notified once the command is done?

brew upgrade | afplay /System/Library/Sounds/Submarine.aiff -v 10

I tried with afplay on Mac as above but the problem is a) stdout is not shown due to the pipe, b) it plays the sound right after the command starts to run rather than waiting until "brew upgrade" is finished.

Any suggestions please?

有帮助吗?

解决方案 2

I think you need

brew upgrade && afplay /System/Library/Sounds/Submarine.aiff -v 10

then the afplay will run if the brew completes successfully.

As a note of explanation, you are asking the shell to determine if both statements ("brew" and "afplay") are true - it is therefore obliged to evaluate the "brew" statement fully (i.e. wait for it to finish) before executing the "afplay" in order to determine whether both statements are true.

其他提示

brew upgrade && say brew upgrade done

leverage the say command and get a custom voice notification

general example:

YOUR_COMMAND && say YOUR_COMMAND done

Thanks Mark. You gave me a great idea.

I haven't noticed &&, || can mean logical operators on shell also. It appears '&& afplay ..' works only when 'brew upgrade' returns 0 which happens most of the time, and '|| afplay ..' works only when 'brew upgrade' returns 1 (or any non-zero) meaning error. I decided to use semicolon ';' so afplay can play sound alarm whatever 'brew upgrade' reterns after job done.

brew upgrade ; afplay /System/Library/Sounds/Submarine.aiff -v 10

EDIT: Now I use the following code in .profile (or .bashrc), which utilizes the advanced notifier tool, terminal-notifier.

function brew { caffeinate -s brew $@; terminal-notifier -title 'Homebrew' -subtitle 'Finished' -message brew' '$1' '$2' '$3 -sound 'recv_mail' -contentImage '/Download/Any/Icon/beer_icon.png';}

Please note:

  1. There must be a whitespace after the left brace '{' for bash syntax.
  2. caffeinate is used to prevent Mac from falling into sleep mode while brew works for a long time. If you remove 'caffeinate -s', you should rename the function name also.
  3. You can install terminal-notifier with brew. -contentImage is optoinal of course.
sleep 30m; for i in {1..10}; do afplay /System/Library/Sounds/Purr.aiff -v 10; done

OP asked for an alarm. This code repeats the sound Purr.aiff 10 times at maximum volume to ensure you can hear it (like an alarm clock). Replace sleep30m with your desired command. If you want it longer, replace 10 in the for loop with 10000.

If you want an infinite alarm (press CTRL-C to exit), try:

sleep 30m; while :; do afplay /System/Library/Sounds/Purr.aiff -v 10; done

If you want other sounds, you may try replacing Purr.aiff with:

  • Basso.aiff
  • List item
  • Frog.aiff
  • Hero.aiff
  • Pop.aiff
  • Submarine.aiff
  • Blow.aiff
  • Funk.aiff
  • Morse.aiff
  • Tink.aiff
  • Bottle.aiff
  • Glass.aiff
  • Ping.aiff
  • Sosumi.aiff

Purr.aiff and Blow.aiff are my personal favorites.

Here is a small function I added to my .zshrc

noti() {
  if [[ $? = 0 ]]; then
    say OK
  else
    say error
  fi
}

Executing some command ; noti from the shell will play 'OK' or 'error' according to the command result.

I found it a better alternative to the usage of && because it notifies both on success and on error.

To directly answer the question, this can be done without installing anything extra, and with just the system alert.

To play the system alert sound after you run "command":

command; printf "\a"

Giorgio's answer is also good, as in"

command; say command is done

To like the continuous alarm idea; I would do something like this to repeat the alarm every 10 seconds:

command; while :; sleep 10; do say command is done; done

Or

command; while :; sleep 2; do printf "\a"; done
  1. Create an alias in your ~/.bash_profile (or equivalent).

    # Play sound
    alias notify='afplay /System/Library/Sounds/Submarine.aiff -v 10'
    
  2. Source your ~/.bash_profile.

    source ~/.bash_profile
    
  3. Run a command that takes a long time. You can either use the notify alias on the same line, or type notify after the command has already started running.

    brew update; notify
    
    # or
    
    brew update
    # oops, I forgot to add "; notify". No worries, just type it now
    notify
    

    As soon as brew update finishes running, notify will execute, playing a sound.

Old thread, but a simple native command that works for me on macOS Catalina:

$ echo -e "\007"

or appended to a command:

$ long_running_program && echo -e "\007"

This essentially echos the BEL (Bell) ASCII character, which makes the beep sound that the native macOS terminal usually emits.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top