0

I'm trying to control error output of a command parametrically but piping command is handled as another parameter. Test scripts below;

...$ cat printOutput.sh 
#!/bin/sh
if [ $# -gt 0 ]; then echo "Wrong parameter $1"; exit; fi
echo "stdout"
echo "errout" >&2

...$ cat test.sh
#!/bin/sh
cmdBase="./printOutput.sh"
if [ -z $1 ]; then
    #Do not pipe
    cmd="$cmdBase"
else
    #Pipe err
    cmd="$cmdBase 2>/dev/null"
fi
echo "`$cmd`"

Error output should only print when --verbose option is selected but it prints anyways.Test script shows that 2>/dev/null piping is handled as a parameter.

...$ ./test.sh --verbose
Wrong parameter 2>/dev/null

...$ sh -x ./test.sh --verbose
+ cmdBase=./printOutput.sh
+ [ -z --verbose ]
+ cmd=./printOutput.sh 2>/dev/null
+ ./printOutput.sh 2>/dev/null
+ echo Wrong parameter 2>/dev/null
Wrong parameter 2>/dev/null

Why/How is the piping handled as an argument here?

Biffen
  • 6,249
  • 6
  • 28
  • 36
HYK
  • 43
  • 6
  • Possible duplicate of [Run a string as a command within a Bash script](https://stackoverflow.com/questions/2355148/run-a-string-as-a-command-within-a-bash-script) – Biffen May 25 '18 at 09:54

1 Answers1

0

It appears to me that output redirection is handled before the variable expansion.

The most obvious way is to handle this within your if statement:

#!/bin/sh
cmdBase="./printOutput.sh"

if [ -z $1 ]; then
   #Do not pipe
   cmdOut="`$cmdBase`"
else
   #Pipe err
   cmdOut="`$cmdBase 2>/dev/null`"
fi

echo "$cmdOut"
Artem Ignatiev
  • 331
  • 2
  • 6
  • Actual command is considerably longer and it will be called multiple times. There would be a lot of code repetition in that case. – HYK May 25 '18 at 15:14
  • 1
    You can wrap it into a function that will do `\`"$@" 2>/dev/null\`` for you based on variable set during parameter parsing – Artem Ignatiev May 25 '18 at 20:38
  • Thanks. Function wrapping worked. Resulting script looks like; `cmdBase="./printOutput.sh"; fnc(){ echo \`$cmdBase $@\`; } fnc 2>/dev/null;` – HYK May 28 '18 at 13:36