Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

conditional redirection in bash

I have a bash script that I want to be quiet when run without attached tty (like from cron). I now was looking for a way to conditionally redirect output to /dev/null in a single line. This is an example of what I had in mind, but I will have many more commands that do output in the script

#!/bin/bash # conditional-redirect.sh if tty -s; then    REDIRECT= else    REDIRECT=">& /dev/null" fi echo "is this visible?" $REDIRECT 

Unfortunately, this does not work:

$ ./conditional-redirect.sh is this visible? $ echo "" | ./conditional-redirect.sh  is this visible? >& /dev/null 

what I don't want to do is duplicate all commands in a with-redirection or with-no-redirection variant:

if tty -s; then    echo "is this visible?" else    echo "is this visible?" >& /dev/null fi 

EDIT:

It would be great if the solution would provide me a way to output something in "quiet" mode, e.g. when something is really wrong, I might want to get a notice from cron.

like image 443
daniel kullmann Avatar asked Jan 06 '12 10:01

daniel kullmann


People also ask

How do I redirect a bash output?

The append >> operator adds the output to the existing content instead of overwriting it. This allows you to redirect the output from multiple commands to a single file. For example, I could redirect the output of date by using the > operator and then redirect hostname and uname -r to the specifications.

What is redirect in bash?

Redirection allows commands' file handles to be duplicated, opened, closed, made to refer to different files, and can change the files the command reads from and writes to. Redirection may also be used to modify file handles in the current shell execution environment.

What does &> mean in bash?

&>word (and >&word redirects both stdout and stderr to the result of the expansion of word. In the cases above that is the file 1 . 2>&1 redirects stderr (fd 2) to the current value of stdout (fd 1).

What is &1 in shell script?

&1 is used to reference the value of the file descriptor 1 (stdout). both Standard output (stdout) and Standard Error (stderr) will redirected to output.


1 Answers

For bash, you can use the line:

exec &>/dev/null 

This will direct all stdout and stderr to /dev/null from that point on. It uses the non-argument version of exec.

Normally, something like exec xyzzy would replace the program in the current process with a new program but you can use this non-argument version to simply modify redirections while keeping the current program.

So, in your specific case, you could use something like:

tty -s if [[ $? -eq 1 ]] ; then     exec &>/dev/null fi 

If you want the majority of output to be discarded but still want to output some stuff, you can create a new file handle to do that. Something like:

tty -s if [[ $? -eq 1 ]] ; then   exec 3>&1 &>/dev/null else    exec 3>&1 fi echo Normal               # won't see this. echo Failure >&3          # will see this. 
like image 178
paxdiablo Avatar answered Nov 04 '22 06:11

paxdiablo