Different Terminal sounds for success and failure on Mac

Save a command's exit status, play a distinct local cue for each outcome and return the original status so the notification cannot disguise a failed build.

Use the command’s exit status to choose a cue, and preserve that status afterward. Otherwise a successful sound player can accidentally become the final result of a failed build.

A small interactive wrapper

This example runs your project’s existing build and returns its result. Use it in an ordinary interactive shell; scripts with set -e need their own deliberate error-handling structure.

notify_build() {
  npm run build
  build_status=$?
  if [ "$build_status" -eq 0 ]; then
    afplay /System/Library/Sounds/Glass.aiff || true
  else
    afplay /System/Library/Sounds/Basso.aiff || true
  fi
  return "$build_status"
}
notify_build

Replace the build command only with one you understand. The || true applies to audio playback so a missing device or sound file does not overwrite the saved build result.

Interpret the result narrowly

Exit status zero means the command reported success. It does not guarantee that the build script ran tests, that the tests cover the changed behaviour or that the generated application is correct.

Read output when a cue sounds. If a build runs through a pipeline, account for the shell’s pipeline-status rules rather than assuming the last command represents every earlier step.

Keep notification logic local

For a one-off task, success-only playback is shorter. For an agent, use the supported connection so command completion and agent lifecycle are not confused.

Sources: macOS afplay -h, POSIX shell exit-status behaviour; TapNoise cue meanings.

About the author

Rudra Satani makes TapNoise. Spotted a mistake? Email support@tapnoise.com, or reach out at @rudraxx13.

Hear TapNoise on your Mac

Every sound is made by TapNoise itself. Try the sounds on the homepage first, then download the app.