Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Is there any way to redirect stdout and stderr via variable like adding command options in script?

For example I have a script:

#!/bin/bash -x
TEST=">/dev/null 2>&1"
OPT='-p -v'
mkdir $OPT 123/123/123 $TEST

I can see that OPT is replaced with -p without any problems and bash interprets it as option. But redirection interprets as directories name.

$ ./test.sh 
+ TEST='>/dev/null 2>&1'
+ OPT='-p -v'
+ mkdir -p -v 123/123/123 '>/dev/null' '2>&1'
mkdir: created directory `123/123'
mkdir: created directory `123/123/123'
mkdir: created directory `>/dev'
mkdir: created directory `>/dev/null'
mkdir: created directory `2>&1'

Is there any way to say bash, that $VAR is redirection, not a dirs names.

PS. May be I'm on wrong way, but I want to make optional verbose or non verbose output from my script. But I need some output even in non-verbose mode, therefore I can't just redirect whole stdout and stderr, only from some commands inside of my script.

share|improve this question
add comment

3 Answers 3

up vote 6 down vote accepted

Another solution could be the following:

#!/bin/bash

verbose=0

exec 3>&1
exec 4>&2

if ((verbose)); then
  echo "verbose=1"
else
  echo "verbose=0"
  exec 1>/dev/null
  exec 2>/dev/null
fi

echo "this should be seen if verbose"
echo "this should always be seen" 1>&3 2>&4

Then add 1>&3 2>&4 only to commands of which you want to see the output.

share|improve this answer
    
Great. This is exactly the thing I watched for. Thank you. –  rush Jan 10 '12 at 13:45
add comment

It is not interpreting it as a "directory name", > is being quoted, so it being treated literally (more specifically, you are sending the string >dev/null 2>&1. Your only way of getting around this is using eval or spawning a new shell.

As for your "verbose" issue alluded to in your question, just do this instead:

verbose=1
if (( verbose )); then
    mkdir -v -p /foo
else
    mkdir -p /foo > /dev/null 2>&1
fi
share|improve this answer
add comment

You have a lot of spaces in your variables, which will not be evaluated properly. You will want to use eval to set that up.

#!/bin/bash -x
TEST=">/dev/null 2>&1"
OPT='-p -v'
eval mkdir $OPT 123/123/123 $TEST

This will allow $OPT to be split into two arguments (-p and -v) instead of one (-p -v) and the same with $TEST. Also changed to use /dev/null since it is very unlikely that you will have a dev directory in the current directory.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.