2015-03-06 2 views
1

Я работаю на машине с python 2.6 и нет, я не могу обновить ее сейчас.
Мне нужна функция subrpocess.check_output, но, как я понял, это примечание, определенное в 2.6. Таким образом, я использовал workaround:python check_output обходной путь в 2.6

try: 
    import subprocess 

    if "check_output" not in dir(subprocess): # duck punch it in! 
     def check_output(*popenargs, **kwargs): 
      r"""Run command with arguments and return its output as a byte string. 

      Backported from Python 2.7 as it's implemented as pure python on stdlib. 

      >>> check_output(['/usr/bin/python', '--version']) 
      Python 2.6.2 
      """ 
      process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs) 
      output, unused_err = process.communicate() 
      retcode = process.poll() 
      if retcode: 
       cmd = kwargs.get("args") 
       if cmd is None: 
        cmd = popenargs[0] 
       error = subprocess.CalledProcessError(retcode, cmd) 
       error.output = output 
       raise error 
      return output 

     subprocess.check_output = check_output 

    # Git Information 
    git_info= { 
     "last_tag"  : subprocess.check_output(['git', 'describe', '--always']), 
     "last_commit" : subprocess.check_output(['git', 'log', '-1', '--pretty=format:\'%h (%ci)\'', '--abbrev-commit']) 
    } 

except Exception, e: 
    raise e 
else: 
    data = git_info 

return data 

Я использую это в сочетании с Django + wsgi.

Предыдущий код всегда дает мне Command '['git', 'describe', '--always']' returned non-zero exit status 128.

Теперь, если я запускаю git describe --always Я получаю правильный вывод, поэтому я не думаю, что проблема есть.

Я понятия не имею, что может вызвать проблему.

EDIT:
Если я использую команду subprocess.check_output(['ls', '-l']) или subprocess.check_output(['pwd']) вещи работать и здесь я понял, что представление вызывается из Django на самом деле работает на /var/www время этого DocumentRoot, указанный в конфигурационном файле Apache.

Реальный файл не находится под /var/www Фактически, все работает на моей локальной машине, где я использую локальный сервер django dev. Таким образом, команда git не будет работать, потому что нет репозитория git под /var/www. Как я могу выполнить оригинал subprocess.check_output(['git', 'describe', '--always']) с его исходного пути (где фактически находится файл python)?

+0

git дает вам текст любой ошибки? Попробуйте 'stderr = subprocess.STDOUT' и напечатайте вывод в обработчике исключений. – tdelaney

+1

Это странный код ... он в одностороннем порядке называет 'git' дважды при импорте без проблем для таких вещей, как текущая рабочая директория - это репозиторий git. – tdelaney

+0

@tdelaney Исключение, созданное 'stderror' is' -2', я не понимаю, это команда git, которая возвращает это значение? Что это значит? – Leonardo

ответ

0

Я решил, передав аргумент cwd check_output, как это было предложено в комментарии.

def get_git_info(): 
    git_info = {} 

    try: 
     import subprocess 
     # subprocess.check_output did not exist in 2.6 
     if "check_output" not in dir(subprocess): # duck punch it in! 
      # workaround/redefinition for the subprocess.check_output() command 
      def check_output(*popenargs, **kwargs): 
       """ Run command with arguments and return its output as a byte string. 
       Backported from Python 2.7 as it's implemented as pure python on stdlib. 
       >>> check_output(['/usr/bin/python', '--version']) 
       Python 2.6.2 
       """ 
       process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs) 
       output, unused_err = process.communicate() 
       retcode = process.poll() 
       if retcode: 
        cmd = kwargs.get("args") 
        if cmd is None: 
         cmd = popenargs[0] 
        error = subprocess.CalledProcessError(retcode, cmd) 
        error.output = output 
        raise error 
        # In case we want the error in string format: 
        # stderr=subprocess.STDOUT 
        # raise Exception(stderr) 
       return output 

      subprocess.check_output = check_output 

     # Set on which dir the git command should be invoked 
     if os.path.isdir(r'/my/git/dir'): 
      cwd = r'/my/git/dir' 
     # If using the django local dev server, then it will invoke the command from the dir where this script is located 
     else: 
      cwd = None 

     # Check that the directory is a git repo: 
     # 'git rev-parse' returns a number !=0 if we are in a git repo 
     if subprocess.check_output(['git', 'rev-parse'], cwd=cwd) != 0: 
      # Git Information 
      git_info = { 
       "last_tag": subprocess.check_output(['git', 'describe', '--always'], cwd=cwd), 
       "last_commit": subprocess.check_output(['git', 'log', '-1', '--pretty=format:\'%h (%ci)\'', '--abbrev-commit'], cwd=cwd), 
      } 

    except Exception, e: 
     log.exception('Problem getting git information') 
     pass 

    # return the git info or an empty dict (defined above) 
    return git_info 
Смежные вопросы