ryanwhocodes Apr 15, 2018 · 4 min read

Sh! Silence Your Bash Scripts by Coding Your Own Silent Flag

How to code a silent flag for running bash scripts with the option of hiding output and errors from the terminal.

In this tutorial, I will show you how you can write a custom shell script to manage your output. You will learn how to control what is printed to the terminal. This article will cover the commands and bash syntax for sending output to the null device and command line arguments that can be shared across multiple scripts.

Contents

Suppressing output

Sometimes it’s important to print output and errors in your terminal, for example when debugging. But logging can also be unwanted — you end up with a terminal full of errors and confirmations when you may just want to know if something worked or not.

Silence output by running a command followed by redirection of standard out and standard error to the null device, which swallows all output given to it and discards it.

[command] &>/dev/null
  • > file redirects stdout to file
  • 1> file redirects stdout to file
  • 2> file redirects stderr to file
  • &> file redirects stdout and stderr to file
  • /dev/null is the null device it takes any input you want and throws it away. It can be used to suppress any output.

It will still return the exit status code, so you can use it in if blocks to run certain commands if the command runs with an exit status of 0 (success).

#!/bin/bash

CONTAINER="$1"

if docker container inspect "$CONTAINER" *&>*/dev/null; then
  echo "Docker container $CONTAINER exists"
  exit 0  
else
  echo "ERROR no docker container $CONTAINER"
  exit 1
fi

Adding a silent option to a shell script

Include a --silent flag following the script or command in the terminal. This will pass it into your script.

./my_script.sh --silent

To capture the silent flag in the script use the bash variable $1 to get the first argument sent to the command. Then set a boolean variable that is switched if the silent flag is present.

#!/bin/bash

SILENT=false

if [[ "$1" == "--silent" ]]; then
  SILENT=true
fi

Use conditional if blocks to check whether the $SILENT boolean is set to true, in which case do not output log statements.

log() {
  if ! $SILENT; then
    echo $1
  fi
}

This can also be applied to commands that you want to silence.

run_command() {
  if $SILENT; then
    $1 &>/dev/null
  else
    $1
  fi
}

Full scripts using a silent flag

Here is a simple script to check the flag works:

#!/bin/bash

SILENT=false

if [[ "$1" == "--silent" ]]; then
  SILENT=true
fi

log() {
  if ! $SILENT; then
    echo $1
  fi
}

run_command() {
  if $SILENT; then
    $1 &>/dev/null
  else
    $1
  fi
}

if $SILENT; then
  log "--silent flag set"
  run_command "echo 'Quiet'"
  exit 0
else
  log "--silent flag not set"
  run_command "echo 'Loud!'"
  exit 1
fi

Which outputs…

./quiet_script.sh
--silent flag not set
Loud!
echo "$?"
1

No output is printed when the –silent flag is present when running the script

./quiet_script.sh --silent
echo "$?"
0

Success!

The below script was written to stop a docker container called rabbitmq-docker if it is running. It includes the option of the --silent flag, and outputs messages by default.

#!/bin/bash

SILENT=false

if [[ "$1" == "--silent" ]]; then
  SILENT=true
fi

log() {
  if ! $SILENT; then
    echo $1
  fi
}

run_command() {
  if $SILENT; then
    $1 &>/dev/null
  else
    $1
  fi
}

if docker ps | grep rabbitmq-docker &>/dev/null; then
  log "Stopping docker container rabbitmq-docker"
  run_command "docker stop $(docker ps | grep rabbitmq-docker | awk '{print $1}')"
  exit 0
else
  log "Could not find running docker container rabbitmq-docker"
  if docker ps -a | grep rabbitmq-docker &>/dev/null; then
    log "Container rabbitmq-docker exists but not running"
  fi
  exit 1
fi

Example output without the flag:

bin/stop.sh
Stopping docker container rabbitmq-docker
c1bcafef8293

bin/stop.sh
Could not find running docker container rabbitmq-docker
Container rabbitmq-docker exists but not running

Now with the flag — so much quieter!

bin/stop.sh --silent
echo "$?"
1

By using the –silent flag you only see the exit status code from running the script to see whether it was successful or not

Using the flag with multiple scripts

You can then pass this flag to another script that operates in the same way to log or suppress output from all the scripts!

#!/bin/bash

SILENT=$1

./bin/stop.sh $SILENT
./bin/remove.sh $SILENT

Find out more

Leaning how to manage the output of your scripts can help you control the information logged. This is useful when you need to run scripts regularly and want a cleaner terminal and log file.