Repository: aws/aws-cli

Issue:
aws <command> help command fails without less installed
I ran into a case where the awscli help commands failed without `groff` & `less` installed. The error message for not having `groff` is pretty straight forward. But the error message about `less` being missing just says `[Errno 2] No such file or directory`.

awscli version:

```
root@redacted:~# aws --version
aws-cli/1.10.25 Python/2.7.9 Linux/4.4.5-15.26.amzn1.x86_64 botocore/1.4.16
```

Running help for the first time:

```
root@redacted:~# aws help

Could not find executable named "groff"
```

So I installed `groff`:

```
root@redacted:~# apt-get install -y -qq groff
```

Then ran help again:

```
root@redacted:~# aws help

[Errno 2] No such file or directory
root@redacted:~# echo $?
255
```

On another machine I found the `--debug` flag so I ran `aws help` with that and found saw that it was trying to call `less` at the end of the output.

```
root@redacted:~# aws --debug help
2016-05-05 16:32:19,477 - MainThread - awscli.clidriver - DEBUG - CLI version: aws-cli/1.10.25 Python/2.7.9 Linux/4.4.5-15.26.amzn1.x86_64 botocore/1.4.16
2016-05-05 16:32:19,477 - MainThread - awscli.clidriver - DEBUG - Arguments entered to CLI: ['--debug', 'help']
2016-05-05 16:32:19,478 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function add_scalar_parsers at 0x7f9faee85e60>
2016-05-05 16:32:19,478 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function inject_assume_role_provider_cache at 0x7f9faee681b8>
2016-05-05 16:32:19,478 - MainThread - botocore.credentials - DEBUG - Skipping environment variable credential check because profile name was explicitly set.
2016-05-05 16:32:19,479 - MainThread - botocore.hooks - DEBUG - Event doc-breadcrumbs.aws: calling handler <bound method ProviderDocumentEventHandler.doc_breadcrumbs of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,479 - MainThread - botocore.hooks - DEBUG - Event doc-title.aws: calling handler <bound method ProviderDocumentEventHandler.doc_title of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,479 - MainThread - botocore.hooks - DEBUG - Event doc-description.aws: calling handler <bound method ProviderDocumentEventHandler.doc_description of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,479 - MainThread - botocore.hooks - DEBUG - Event doc-description.aws: calling handler <function add_paging_description at 0x7f9faf01a5f0>
2016-05-05 16:32:19,480 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-start.aws: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_start of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,480 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-option.aws.debug: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,480 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-option.aws.endpoint-url: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,480 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-option.aws.no-verify-ssl: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,480 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-option.aws.no-paginate: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,481 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-option.aws.output: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,481 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-option.aws.query: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,481 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-option.aws.profile: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,481 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-option.aws.region: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,481 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-option.aws.version: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,482 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-option.aws.color: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,482 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-option.aws.no-sign-request: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,482 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-option.aws.ca-bundle: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,482 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-option.aws.cli-read-timeout: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,482 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-option.aws.cli-connect-timeout: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,483 - MainThread - botocore.hooks - DEBUG - Event doc-synopsis-end.aws: calling handler <bound method ProviderDocumentEventHandler.doc_synopsis_end of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,483 - MainThread - botocore.hooks - DEBUG - Event doc-options-start.aws: calling handler <bound method ProviderDocumentEventHandler.doc_options_start of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,483 - MainThread - botocore.hooks - DEBUG - Event doc-option.aws.debug: calling handler <bound method ProviderDocumentEventHandler.doc_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,483 - MainThread - botocore.hooks - DEBUG - Event doc-option.aws.endpoint-url: calling handler <bound method ProviderDocumentEventHandler.doc_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,484 - MainThread - botocore.hooks - DEBUG - Event doc-option.aws.no-verify-ssl: calling handler <bound method ProviderDocumentEventHandler.doc_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,484 - MainThread - botocore.hooks - DEBUG - Event doc-option.aws.no-paginate: calling handler <bound method ProviderDocumentEventHandler.doc_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,484 - MainThread - botocore.hooks - DEBUG - Event doc-option.aws.output: calling handler <bound method ProviderDocumentEventHandler.doc_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,485 - MainThread - botocore.hooks - DEBUG - Event doc-option.aws.query: calling handler <bound method ProviderDocumentEventHandler.doc_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,485 - MainThread - botocore.hooks - DEBUG - Event doc-option.aws.profile: calling handler <bound method ProviderDocumentEventHandler.doc_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,485 - MainThread - botocore.hooks - DEBUG - Event doc-option.aws.region: calling handler <bound method ProviderDocumentEventHandler.doc_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,486 - MainThread - botocore.hooks - DEBUG - Event doc-option.aws.version: calling handler <bound method ProviderDocumentEventHandler.doc_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,486 - MainThread - botocore.hooks - DEBUG - Event doc-option.aws.color: calling handler <bound method ProviderDocumentEventHandler.doc_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,486 - MainThread - botocore.hooks - DEBUG - Event doc-option.aws.no-sign-request: calling handler <bound method ProviderDocumentEventHandler.doc_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,487 - MainThread - botocore.hooks - DEBUG - Event doc-option.aws.ca-bundle: calling handler <bound method ProviderDocumentEventHandler.doc_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,487 - MainThread - botocore.hooks - DEBUG - Event doc-option.aws.cli-read-timeout: calling handler <bound method ProviderDocumentEventHandler.doc_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,487 - MainThread - botocore.hooks - DEBUG - Event doc-option.aws.cli-connect-timeout: calling handler <bound method ProviderDocumentEventHandler.doc_option of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,488 - MainThread - botocore.hooks - DEBUG - Event doc-subitems-start.aws: calling handler <bound method ProviderDocumentEventHandler.doc_subitems_start of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,488 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.acm: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,488 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.apigateway: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,488 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.autoscaling: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,489 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.cloudformation: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,489 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.cloudfront: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,489 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.cloudhsm: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,489 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.cloudsearch: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,489 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.cloudsearchdomain: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,490 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.cloudtrail: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,490 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.cloudwatch: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,490 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.codecommit: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,490 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.codepipeline: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,490 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.cognito-identity: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,491 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.cognito-idp: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,491 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.cognito-sync: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,491 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.configservice: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,491 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.configure: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,491 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.datapipeline: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,491 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.deploy: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,492 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.devicefarm: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,492 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.directconnect: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,492 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.dms: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,492 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.ds: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,493 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.dynamodb: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,493 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.dynamodbstreams: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,493 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.ec2: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,493 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.ecr: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,493 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.ecs: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,494 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.efs: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,494 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.elasticache: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,494 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.elasticbeanstalk: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,494 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.elastictranscoder: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,494 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.elb: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,495 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.emr: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,495 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.es: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,495 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.events: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,495 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.firehose: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,495 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.gamelift: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,496 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.glacier: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,496 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.help: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,496 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.iam: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,496 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.importexport: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,496 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.inspector: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,497 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.iot: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,497 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.iot-data: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,497 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.kinesis: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,497 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.kms: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,497 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.lambda: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,497 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.logs: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,498 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.machinelearning: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,498 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.marketplacecommerceanalytics: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,498 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.meteringmarketplace: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,498 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.opsworks: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,499 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.rds: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,499 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.redshift: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,499 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.route53: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,499 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.route53domains: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,499 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.s3: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,500 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.s3api: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,500 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.sdb: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,500 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.ses: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,500 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.sns: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,500 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.sqs: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,501 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.ssm: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,501 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.storagegateway: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,501 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.sts: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,501 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.support: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,501 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.swf: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,502 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.waf: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,502 - MainThread - botocore.hooks - DEBUG - Event doc-subitem.aws.workspaces: calling handler <bound method ProviderDocumentEventHandler.doc_subitem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,503 - MainThread - botocore.hooks - DEBUG - Event doc-relateditems-start.aws: calling handler <bound method ProviderDocumentEventHandler.doc_relateditems_start of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,503 - MainThread - botocore.hooks - DEBUG - Event doc-relateditem.aws.aws help topics: calling handler <bound method ProviderDocumentEventHandler.doc_relateditem of <awscli.clidocs.ProviderDocumentEventHandler object at 0x7f9fae9519d0>>
2016-05-05 16:32:19,566 - MainThread - awscli.help - DEBUG - Running command: ['groff', '-m', 'man', '-T', 'ascii']
2016-05-05 16:32:19,582 - MainThread - awscli.help - DEBUG - Running command: ['less', '-R']
2016-05-05 16:32:19,584 - MainThread - awscli.clidriver - DEBUG - Exception caught in main()
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/awscli/clidriver.py", line 186, in main
    return command_table[parsed_args.command](remaining, parsed_args)
  File "/usr/local/lib/python2.7/dist-packages/awscli/help.py", line 264, in __call__
    self.renderer.render(self.doc.getvalue())
  File "/usr/local/lib/python2.7/dist-packages/awscli/help.py", line 82, in render
    self._send_output_to_pager(converted_content)
  File "/usr/local/lib/python2.7/dist-packages/awscli/help.py", line 130, in _send_output_to_pager
    p = self._popen(cmdline, stdin=PIPE)
  File "/usr/local/lib/python2.7/dist-packages/awscli/help.py", line 91, in _popen
    return Popen(*args, **kwargs)
  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1335, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory
2016-05-05 16:32:19,587 - MainThread - awscli.clidriver - DEBUG - Exiting with rc 255

[Errno 2] No such file or directory
```

So I installed `less`:

```
root@redacted:~# apt-get install -y -qq less
```

Ran help again and it worked:

```
root@redacted:~# aws help
root@redacted:~# echo $?
0
```

(yes, I know that not having `less` installed is pretty rare but I thought I should report the bug anyway)



Discussion:
Interesting. I think for this case we can either have a better error message or fall back to or just print it all out without a pager.


Resolving patch:
diff --git a/awscli/help.py b/awscli/help.py
--- a/awscli/help.py
+++ b/awscli/help.py
@@ -12,6 +12,7 @@
 # language governing permissions and limitations under the License.
 import logging
 import os
+import sys
 import platform
 import shlex
 from subprocess import Popen, PIPE
@@ -62,6 +63,8 @@ class PagingHelpRenderer(object):
     a particular platform.
 
     """
+    def __init__(self, output_stream=sys.stdout):
+        self.output_stream = output_stream
 
     PAGER = None
 
@@ -114,6 +117,12 @@ def _convert_doc_content(self, contents):
 
     def _send_output_to_pager(self, output):
         cmdline = self.get_pager_cmdline()
+        if not self._exists_on_path(cmdline[0]):
+            LOG.debug("Pager '%s' not found in PATH, printing raw help." %
+                      cmdline[0])
+            self.output_stream.write(output.decode('utf-8') + "\n")
+            self.output_stream.flush()
+            return
         LOG.debug("Running command: %s", cmdline)
         with ignore_ctrl_c():
             # We can't rely on the KeyboardInterrupt from


Test patch:
diff --git a/tests/unit/test_help.py b/tests/unit/test_help.py
--- a/tests/unit/test_help.py
+++ b/tests/unit/test_help.py
@@ -19,6 +19,7 @@
 
 import mock
 
+from awscli.compat import six
 from awscli.help import PosixHelpRenderer, ExecutableNotFoundError
 from awscli.help import WindowsHelpRenderer, ProviderHelpCommand, HelpCommand
 from awscli.help import TopicListerCommand, TopicHelpCommand
@@ -40,11 +41,15 @@ def _popen(self, *args, **kwargs):
 
 
 class FakePosixHelpRenderer(HelpSpyMixin, PosixHelpRenderer):
-    pass
+    def __init__(self, output_stream=sys.stdout):
+        HelpSpyMixin.__init__(self)
+        PosixHelpRenderer.__init__(self, output_stream)
 
 
 class FakeWindowsHelpRenderer(HelpSpyMixin, WindowsHelpRenderer):
-    pass
+    def __init__(self, output_stream=sys.stdout):
+        HelpSpyMixin.__init__(self)
+        WindowsHelpRenderer.__init__(self, output_stream)
 
 
 class TestHelpPager(unittest.TestCase):
@@ -96,10 +101,23 @@ def test_pager_with_args(self):
     def test_no_groff_exists(self):
         renderer = FakePosixHelpRenderer()
         renderer.exists_on_path['groff'] = False
-        with self.assertRaisesRegexp(ExecutableNotFoundError,
-                                     'Could not find executable named "groff"'):
+        expected_error = 'Could not find executable named "groff"'
+        with self.assertRaisesRegexp(ExecutableNotFoundError, expected_error):
             renderer.render('foo')
 
+    @skip_if_windows('Requires POSIX system.')
+    def test_no_pager_exists(self):
+        fake_pager = 'foobar'
+        os.environ['MANPAGER'] = fake_pager
+        stdout = six.StringIO()
+        renderer = FakePosixHelpRenderer(output_stream=stdout)
+        renderer.exists_on_path[fake_pager] = False
+
+        renderer.exists_on_path['groff'] = True
+        renderer.mock_popen.communicate.return_value = (b'foo', '')
+        renderer.render('foo')
+        self.assertEqual(stdout.getvalue(), 'foo\n')
+
     def test_shlex_split_for_pager_var(self):
         pager_cmd = '/bin/sh -c "col -bx | vim -c \'set ft=man\' -"'
         os.environ['PAGER'] = pager_cmd
@@ -109,6 +127,7 @@ def test_shlex_split_for_pager_var(self):
     def test_can_render_contents(self):
         renderer = FakePosixHelpRenderer()
         renderer.exists_on_path['groff'] = True
+        renderer.exists_on_path['less'] = True
         renderer.mock_popen.communicate.return_value = ('rendered', '')
         renderer.render('foo')
         self.assertEqual(renderer.popen_calls[-1][0], (['less', '-R'],))
@@ -133,6 +152,7 @@ def _is_pager_call(self, args):
         renderer = CtrlCRenderer()
         renderer.mock_popen.communicate.return_value = ('send to pager', '')
         renderer.exists_on_path['groff'] = True
+        renderer.exists_on_path['less'] = True
         renderer.render('foo')
         last_call = renderer.mock_popen.communicate.call_args_list[-1]
         self.assertEqual(last_call, mock.call(input='send to pager'))