0

I have a bash script that runs a bunch of other commands (e.g. docker). I want the script to be able to capture all the output into a variable and then echo out a custom return at the end.

Example:

#!/usr/bin/env bash
set -euo pipefail

# Capture into this (PSEUDO CODE)
declare CapturedOutput
$(Capture Output > CapturedOutput)

# Run some commands like...
docker-compose ... up -d

# Stop capturing (PSEUDO CODE)
$(Stop Capture Output > CapturedOutput)

echo "something"

So if someone called my script like ./runit.sh and the docker command had output, they wouldn't see it but would only see:

> ./runit.sh

something
5
  • Possible duplicate of Capture output of a bash command, parse it and store into different bash variables Commented Aug 14, 2019 at 19:21
  • @LéaGris It's not a duplicate. That's capturing the output from outside the script. I want to capture it inside Commented Aug 14, 2019 at 19:22
  • Is it just the output of docker you want to capture in a variable? Commented Aug 14, 2019 at 19:29
  • 1
    Are you actually going to use CapturedOutput? Redirecting a command group to /dev/null might be sufficient. Commented Aug 14, 2019 at 19:33
  • @DavidC.Rankin No, I want to redirect the output of all the commands I run in the script Commented Aug 15, 2019 at 14:02

2 Answers 2

1

The most straightforward way to capture output into a variable is to use command substitution. You can easily wrap that around a large chunk of script:

#!/usr/bin/env bash
set -euo pipefail

# To capture standard error, too:
# exec 3>&2 2>&1

CapturedOutput=$(

# Run some commands like...
docker-compose ... up -d

)

# To restore standard error:
# exec 2>&3- 

echo "something"

The caveat is that the commands from which output is being captured run in a subshell, but I'm having trouble coming up with an alternative for capturing into a variable in the same shell in which the commands themselves run.

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

6 Comments

Would this work differently than wrapping it all in a function?
I'm uncertain what specific alternative you have in mind, @DonRhummy. You could put docker-compose and all the other commands whose output is to be captured in a function, and that might indeed be a sensible thing to do, but you would still need to use command substitution -- either inside the function or of the function call -- to capture the output to a variable.
Unfortunately, this sin't working. I think because it's in a subshell now, docker is unable to mount the volumes. I get the error: ERROR: for redis Cannot start service redis: error while creating mount source path '/host_mnt/c/Users/myname/redis-test/customstartup.sh': mkdir /host_mnt/c: file exists
@DonRhummy, I believe you that your particular script, written with use of a command substitution as I have described, does not successfully do the job you want it to do. It's not at all clear, however, why running the commands in a subshell would be directly responsible for the particular error described in that message, and in fact I find the prospect dubious. The issues with use of subshells largely revolve around (not) communicating information back to the parent shell, and especially around redirections and shell variable modifications performed in the subshell not affecting the parent.
I know, but when I run it not in a subshell it works, but the moment I put it in a subshell it throws the error
|
0

I think you want to look at the "Command Substitution" section on bash's man page.

To translate the pseudocode in your question to bash's format, something like:

CapturedOutput=$(docker-compose ... up -d)
CapturedOutput=$CapturedOutput $(docker-compose ... up -d)
...

Comments

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.