0

I'm running a Python script from within a Bash script and have been trying to assign that command's stderr into a Bash variable. I think the issue is with how I'm referencing the variable, but am having trouble trying to identify what that problem is...

Here's what I'm doing and what I've tried:

#errorMessage=""


python test.py 2> $errorMessage

echo $errorMessage

Results in error code: test.sh: line 4: $errorMessage: ambiguous redirect

And with errorMessage actually declared, I get the same error message:

errorMessage=""


python test.py 2> $errorMessage

echo $errorMessage

The python file test.py is set to write to stderr. I'm ultimately trying to check if this variable errorMessage is empty or not to do more error handling; is checking the length of errorMessage fine?

simplycoding
  • 2,770
  • 9
  • 46
  • 91
  • 1
    `2>$errorMessage` redirects to the **file** named by the contents of the variable `errorMessage`. An empty string isn't a valid filename, hence "ambiguous redirect". – Charles Duffy Mar 30 '17 at 19:52
  • Ah, thanks for the clarification. From reading the link that my question seems to be a duplicate of, everyone there answered with redirecting to a file. So I'm guessing redirecting to a variable is not allowed at all? – simplycoding Mar 30 '17 at 19:58
  • There are absolutely answers in that question that use command substitutions to capture stderr, rather than redirecting to files. Look harder. – Charles Duffy Mar 30 '17 at 19:59
  • ...that said, the reason the *accepted* answer there redirects to a file is because the OP wanted to be able to run stdout into a larger pipeline, and doing *that* in conjunction with capturing stderr is a lot more difficult. – Charles Duffy Mar 30 '17 at 20:00
  • ...actually, if I had to guess at a cause of the misunderstanding... perhaps you're reading `2>&1` as redirecting to a file named `1` or `&1`? That's not what it does. – Charles Duffy Mar 30 '17 at 20:01
  • (That said -- if your `test.py` were correctly written, it would be reflecting whether or not it exited in an error -- or if whatever test it was running was successful -- in its *exit status*, so you wouldn't need to check contents written to stderr to make this determination). – Charles Duffy Mar 30 '17 at 20:06
  • Yeah so it looks like most people had their command wrapped into a variable, like the top accepted answer. I'm still a little confused since they're redirecting to stdout, which I don't need to do. Is this fine?: `errorMessage=$( { python test.py } 2 )` – simplycoding Mar 31 '17 at 18:02
  • You **do** actually need to redirect to stdout: stdout is the only thing that's captured in a command substitution. Thus, it's the only thing assigned to the variable. `errorMessage=$( python test.py 2>&1 >/dev/null )` will thus discard the original stdout, but capture the original stderr into the variable named `errorMessage`. – Charles Duffy Mar 31 '17 at 20:45
  • Okay, so command substitution is still the only way to do this? Or is there another way that I'm just not aware of? – simplycoding Mar 31 '17 at 20:52
  • "only way" is a little bit strong of a phrase -- there are answers other than command substitution, but they're *bad* answers -- unidiomatic code with significant caveats. (I don't really agree that it's accurate to describe a command substitution as "wrapped in a variable", btw -- you're storing the command's output, not the command itself). – Charles Duffy Mar 31 '17 at 20:55
  • As an example of one of those unidiomatic answers: `IFS= read -r -d '' errorMessage < <(python test.py 2>&1 >/dev/null && printf '\0')` will do the job, but it's bash-only and cuts off output at the first literal NUL if any exist. – Charles Duffy Mar 31 '17 at 20:57

0 Answers0