Aws-cli: Set sensible pager defaults for output

Created on 1 Apr 2020  Â·  11Comments  Â·  Source: aws/aws-cli

Right now the output paginates. This is great for interactive human usage, but "set an environment variable you likely didn't know existed" for using v2 with scripts isn't ideal.

Instead a "generally does the right thing by default approach" such as:

if not sys.stdout.isatty() and not pager_config_set_explicitly:
    pager = None

solves for the most common case. Namely, "I want to use a pager if you're outputting to a shell, but if you're being invoked via script I almost certainly don't want to use a pager."

git log vs. git log | cat exhibits this behavior, as a citation.

feature-request pager v2

Most helpful comment

Here's a simplified version of the shell script I'm running:

#!/bin/bash

for fn in fn1 fn2 fn3; do
  aws lambda invoke --function-name $fn1 ${fn1}.txt
  aws logs filter-log-events --log-group-name "/aws/lambda/${fn1}" --query 'events[].message' --output text
done

When I run this script (ie, using ./myscript.sh), both of those aws commands page – I have to press q, q, q, etc for each loop, for each command.

Previously I could just run this script and the output of all commands would be dumped into my terminal

All 11 comments

Hmmm. Emulating git log won't solve the problem I'm seeing. I have many scripts that invoke aws but don't redirect output. Will be especially annoying in CI environments where everyone will essentially need to set a new env var

Are those scripts returning raw aws cli output?

In a CI environment it shouldn't be returning to a TTY at all...

Yes, just returning raw AWS CLI output. Many aws commands will do this (any time you want to perform a command as opposed to a query)

(good point about CI envs – not sure what they do with regards to emulating a TTY, eg for color purposes, etc)

Hi,
I'm not really understanding @mhart issue, but as far as trying to automate the output pagination depending on whether or not it is being called on a script, that sounds reasonable and considering this has been a very common issue since V2 release there'd be a lot of interest on this.
Would you be interested in making a PR??

Oh, I'm totally fine if you can figure out if it's being called from a script or not – I'm just not sure how you do that? Detecting if it's being piped somewhere is a slightly separate issue

Hmm. Is this actually a problem?

```import os
import sys

This conditional triggers, and the message is printed.

if not sys.stdout.isatty():
print("No TTY detected.")

stacks = os.popen("./build/scripts-3.8/aws cloudformation describe-stacks").read()

And this next line prints the entire return without paging or truncation.

print(stacks)
```

If I'm missing something, please feel free to paste a quick shell script repro...

Here's a simplified version of the shell script I'm running:

#!/bin/bash

for fn in fn1 fn2 fn3; do
  aws lambda invoke --function-name $fn1 ${fn1}.txt
  aws logs filter-log-events --log-group-name "/aws/lambda/${fn1}" --query 'events[].message' --output text
done

When I run this script (ie, using ./myscript.sh), both of those aws commands page – I have to press q, q, q, etc for each loop, for each command.

Previously I could just run this script and the output of all commands would be dumped into my terminal

Also running into this - I'm all for "sensible detection", but frankly, setting this by default isn't the best option. I like the idea of leveraging a pager, but _please_ don't shove it down your users' throats. It erodes trust and causes your end-users unnecessary pain when an opt-in config option would've been fine.

We have good chunks of our tooling built out in shell scripts which we expect a human operator to run. In many cases, these are interactive tools which invoke awscli commands, and we'll show those outputs because it's handy. Sometimes the script is as simple as

#/bin/bash
set -e
echo "== Doing CFN Deploy =="
aws cloudformation deploy ...

Now that awscliv2 is out, with the default pager behavior, I have a team member who is adding

export AWS_PAGER=""

to the top of all of our scripts. I think this is ugly and awful, but he rightly points out that we don't want scripts which used to run to completion on their own locking up and confusing people if they use cliv2.


isatty() doesn't work perfectly because it doesn't tell you if the usage is _interactive_, which is really what you want to detect.

I have used os.getenv("PS1") is not None successfully and been happy with the results.
Because PS1 is never normally exported, script invocations won't see it. I also doubt it would be set in CI environments, but can't promise anything there.

I can't say it will be perfect, but I think it would be better than the behavior today _and_ better than checking if stdout is a tty. There are other approaches too, like os.getenv("PS1") is not None and sys.stdout.isatty() -- it just depends on how you want to target things.

I'd be happy to submit a PR if people think this is a good idea.

Cross referencing: I've submitted a a PR to remove the PAGER environment variable from the list to look for. See #5398

Was this page helpful?
0 / 5 - 0 ratings