/lib/ansible/utils/cmd_functions.py

https://github.com/ajanthanm/ansible · Python · 59 lines · 32 code · 7 blank · 20 comment · 12 complexity · b5eedd77a0d662d0db64e4041a0cd57d MD5 · raw file

  1. # (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
  2. #
  3. # This file is part of Ansible
  4. #
  5. # Ansible is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # Ansible is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
  17. import os
  18. import sys
  19. import shlex
  20. import subprocess
  21. import select
  22. def run_cmd(cmd, live=False, readsize=10):
  23. #readsize = 10
  24. cmdargs = shlex.split(cmd)
  25. p = subprocess.Popen(cmdargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  26. stdout = ''
  27. stderr = ''
  28. rpipes = [p.stdout, p.stderr]
  29. while True:
  30. rfd, wfd, efd = select.select(rpipes, [], rpipes, 1)
  31. if p.stdout in rfd:
  32. dat = os.read(p.stdout.fileno(), readsize)
  33. if live:
  34. sys.stdout.write(dat)
  35. stdout += dat
  36. if dat == '':
  37. rpipes.remove(p.stdout)
  38. if p.stderr in rfd:
  39. dat = os.read(p.stderr.fileno(), readsize)
  40. stderr += dat
  41. if live:
  42. sys.stdout.write(dat)
  43. if dat == '':
  44. rpipes.remove(p.stderr)
  45. # only break out if we've emptied the pipes, or there is nothing to
  46. # read from and the process has finished.
  47. if (not rpipes or not rfd) and p.poll() is not None:
  48. break
  49. # Calling wait while there are still pipes to read can cause a lock
  50. elif not rpipes and p.poll() == None:
  51. p.wait()
  52. return p.returncode, stdout, stderr