9

I am trying to capture the output of an aws ec2 delete-snapshot in a Bash script command but I cannot get anything to capture the output. I have tried result=$(command), result=`command` etc. but when I try to echo $result there is nothing there.

Here is some example output.

root@host:~# aws ec2 delete-snapshot --snapshot-id vid --output json>test

A client error (InvalidParameterValue) occurred when calling the DeleteSnapshot operation: Value (vid) for parameter snapshotId is invalid. Expected: 'snap-...'.
root@host:~# aws ec2 delete-snapshot --snapshot-id vid>test

A client error (InvalidParameterValue) occurred when calling the DeleteSnapshot operation: Value (vid) for parameter snapshotId is invalid. Expected: 'snap-...'.
root@host:~# cat test
root@host:~# testing=$(aws ec2 delete-snapshot --snapshot-id vid)

A client error (InvalidParameterValue) occurred when calling the DeleteSnapshot operation: Value (vid) for parameter snapshotId is invalid. Expected: 'snap-...'.
root@host:~# echo $testing

root@host:~#

I need to automate creation and deletion of snapshots, but I can't capture the output.

Has anyone else ran into this issue?

MadHatter
  • 79,770
  • 20
  • 184
  • 232
JoshZ
  • 93
  • 1
  • 1
  • 3

4 Answers4

12

The > operator only redirects stdout ("standard output"), or "file descriptor 1". Error messages are usually printed on a different file descriptor, 2, stderr, ("standard error"). On your terminal screen, you are seeing both stdout and stderr.

The > operator is really more just a shortcut for 1>, and again, only redirects stdout. The 2> operator is similar to 1> but it instead of redirecting stdout, it redirects stderr.

user@host$ echo hello world >/dev/null
user@host$ echo hello world 1>/dev/null
user@host$ echo hello world 2>/dev/null
hello world
user@host$

So, to redirect both stdout and stderr to the same file, use >file 2>&1.

user@host$ echo hi 2>/dev/null 1>&2
user@host$

This says, "redirect the echo's stderr to /dev/null, and redirect stdout to stderr.

user@host$ curl --invalid-option-show-me-errors >/dev/null
curl: option --invalid-option-show-me-errors: is unknown
try 'curl --help' or 'curl --manual' for more information

user@host$ curl --invalid-option-show-me-errors 2>/dev/null
user@host$ 
user@host$ curl --invalid-option-show-me-errors >/dev/null 2>&1
user@host$ 

In modern Bash, you can also use &> to redirect both streams to the same file:

user@host$ curl --invalid-option-show-me-errors &>/dev/null
user@host$ 

So for you, specifically, use:

aws ec2 delete-snapshot --snapshot-id vid --output json >test 2>&1

Or

aws ec2 delete-snapshot --snapshot-id vid --output json &>test
Will
  • 1,147
  • 10
  • 26
5

If you want to capture both stdout and stderr in a variable, try:

RESULT="$(aws ec2 delete-snapshot --snapshot-id vid --output json 2>&1)"

if ! [[ $RESULT =~ "Successfully deleted snapshot" ]]; then
  echo "ERROR while deleting snapshot"
  echo "$RESULT"
  exit 1
fi

...
Sam Houston
  • 151
  • 1
  • 1
5

Error output will be written to stderr, not stdout, and you are only redirecting stdout. If you want to capture stderr as well, you need to add 2>&1, e.g.:

aws ec2 delete-snapshot --snapshot-id vid --output json >test 2>&1
Will
  • 1,147
  • 10
  • 26
Craig Miskell
  • 4,216
  • 1
  • 16
  • 16
1

I faced this issue as well when I tried to insert an ACW CLI output into a variable. What I did to overcome this issue was:

token=$(aws <command> | jq -r '.NextToken')
echo $token
bjoster
  • 4,805
  • 5
  • 25
  • 33