Why can't I capture AWS EC2 CLI Output in Bash?
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
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
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
...