Repository: ansible/ansible

Issue:
ansible-vault view shows less program info before file content for small files
##### ISSUE TYPE
- Bug Report
##### COMPONENT NAME

ansible-vault
##### ANSIBLE VERSION

```
ansible 2.1.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
```
##### CONFIGURATION

ansible.cfg:

```
[defaults]
vault_password_file = /path/to/password/file
```

No aliases for `less` are defined in shell (/bin/bash).
##### OS / ENVIRONMENT

Ubuntu 14.04 Trusty
bash: 4.3.11
less: 458
`$PAGER` environment variable is not set.
##### SUMMARY

For a small vault encrypted file, that cat fit in terminal window, `ansible-vault view <filename>` shows `less` program info before file content. Problem occurs for any type of password: from file and from console.
##### STEPS TO REPRODUCE

```
echo test > /tmp/test
ansible-vault encrypt /tmp/test
ansible-vault view /tmp/test
```
##### EXPECTED RESULTS

```
test
```
##### ACTUAL RESULTS

```
Using /etc/ansible/ansible.cfg as config file
Vault password: 
less 458 (GNU regular expressions)
Copyright (C) 1984-2012 Mark Nudelman

less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less
test
```



Discussion:
I have this problem too

I discovered, that `ansible-vault view <filename> | cat` does not produce excessive help output. So, it seems that bug appears only if stdout is a real tty, not just a pipe.

If I do `export PAGER=less` before calling `ansible-vault`, bug disappears. But if I do `unset PAGER`, it appears again.

I have a seem problem on Jessie container, but not on my host.
Same version a both (2.1.0.0).

On Debian Jessie

```
jenkins@jenkins:~/projects-deployment/adp-mini-site$ ansible-vault view vars/credential.yml
Vault password:
less 458 (GNU regular expressions)
Copyright (C) 1984-2012 Mark Nudelman

less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less
# credentials.yml : Credentials

# integration
INT_DB_PASSWORD: xxxxxx
```

On Fedora 24

```
stan@m9-94:~/projects-deployment/adp-mini-site$ ansible-vault view vars/credential.yml
Vault password:
# credentials.yml : Credentials

# integration
INT_DB_PASSWORD: xxxxxx
....
```

https://github.com/ansible/ansible/issues/15685 and https://github.com/ansible/ansible/pull/15720 would seem related

@shannara  what are the PAGER, LESS, and LESS_OPTS environment variables set to on the debian jessie systems that show the problem?

(Or any of the LESS\* env options...)

@alikins : on Ubuntu 14.04 Trusty:

```
selivan@work:~$ echo $PAGER

selivan@work:~$ echo $LESS

selivan@work:~$ echo $LESS_OPTS

selivan@work:~$ echo $LESSOPEN
| /usr/bin/lesspipe %s
selivan@work:~$ echo $LESSCLOSE
/usr/bin/lesspipe %s %s
```

Bug reproduces with this environment. Less version is 458. When I unset `LESSOPEN` ahd `LESSCLOSE`, bug still reproduces.

But when I do `export PAGER=less`, bug disappears.

@alikins : on Debian Jessie : 

```
jenkins@jenkins:~/projects-deployment/adp-mini-site$ echo $PAGER

jenkins@jenkins:~/projects-deployment/adp-mini-site$ echo $LESS

jenkins@jenkins:~/projects-deployment/adp-mini-site$ echo $LESS_OPTS

jenkins@jenkins:~/projects-deployment/adp-mini-site$ echo $LESSOPEN

jenkins@jenkins:~/projects-deployment/adp-mini-site$ echo $LESSCLOSE
```

All vars is empty.

The following seems to resolve this problem for me:

```
diff --git a/lib/ansible/cli/__init__.py b/lib/ansible/cli/__init__.py
index 3176d9c..48def42 100644
--- a/lib/ansible/cli/__init__.py
+++ b/lib/ansible/cli/__init__.py
@@ -479,10 +479,13 @@ class CLI(object):
                 display.display(text)
             else:
                 self.pager_pipe(text, os.environ['PAGER'])
-        elif subprocess.call('(less --version) &> /dev/null', shell = True) == 0:
-            self.pager_pipe(text, 'less')
         else:
-            display.display(text)
+            p = subprocess.Popen('less --version', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            p.communicate()
+            if p.returncode == 0:
+                self.pager_pipe(text, 'less')
+            else:
+                display.display(text)

     @staticmethod
     def pager_pipe(text, cmd):
```

Instead of trying to capture the output of `less --version` in the shell, let `subprocess` capture it.  This likely wasn't done before, as `subprocess.call` recommends not using `PIPE`, however we can follow the recommendation and use `Popen` instead of `call`.

@sivel yes, guys had found it: PR https://github.com/ansible/ansible/pull/15720 is merged.


Resolving patch:
diff --git a/lib/ansible/cli/__init__.py b/lib/ansible/cli/__init__.py
--- a/lib/ansible/cli/__init__.py
+++ b/lib/ansible/cli/__init__.py
@@ -479,10 +479,13 @@ def pager(self, text):
                 display.display(text)
             else:
                 self.pager_pipe(text, os.environ['PAGER'])
-        elif subprocess.call('(less --version) &> /dev/null', shell = True) == 0:
-            self.pager_pipe(text, 'less')
         else:
-            display.display(text)
+            p = subprocess.Popen('less --version', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            p.communicate()
+            if p.returncode == 0:
+                self.pager_pipe(text, 'less')
+            else:
+                display.display(text)
 
     @staticmethod
     def pager_pipe(text, cmd):


Test patch: