0

I'm writing a test script and it has a lot of repetition in it, and I'm looking for ways to reduce these code duplication. So I thought it would be nice to programmatically create the redirect part of the commands.

Here is a minimal example: (In the real script I would generate different output file names in x())

#!/bin/bash

set -x

x() {
  echo '> out.txt 2> err.txt'
}

./someProgram $(x)

My hope would be that stdout would end up in out.txt and stderr in err.txt. But bash quotes the string. So the resulting command is ./someProgram '>' out.txt '2>' err.txt instead of ./someProgram > out.txt 2> err.txt.

Here is the output of the example:

++ x
++ echo '> out.txt   2> err.txt'
+ ./someProgram '>' out.txt '2>' err.txt
.....

So is there a possibility that '>' and '2>' won't get quoted?

2
  • 1
    Perhaps you just want exec > out.txt 2> err.txt Commented Mar 21, 2020 at 23:49
  • 1
    Have you considered to invert the flow? Instead of someProgram $(x) you can do it like this: x someProgram, i.e. the x function accepts an executable along with optional arguments and redirects its stdout and stderr as you wish Commented Mar 21, 2020 at 23:55

1 Answer 1

2

It's hard to way without more context, but probably you just want to use exec judiciously. I won't vouch for the portability of the following, but in bash 5.0.16 you can do:

x() { shift; "$@"; } > $1.out 2> $1.err
x filename ./someProgram

To run ./someProgram with the output directed to filename.out and the error stream written to filenmae.err

Sign up to request clarification or add additional context in comments.

2 Comments

Wrt I won't vouch for the portability of the following standard is a bit unclear on this, it says The operands to the command temporarily shall become the positional parameters during the execution of the compound-command; but I think they should support this usage, it's really cool.
exec was not the right approach but re-thinking the flow. I use a similar approach to yours with shift. Thanks for your insight/inspiration!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.