2015-02-16 4 views
-2

Не могу понять, как закрыть оболочку bash, которая была запущена через Popen. Я нахожусь в окнах и пытаюсь автоматизировать некоторые вещи ssh. Это гораздо проще сделать это с помощью bash оболочки, которая поставляется с мерзавцем, и поэтому я ссылающегося на него через Popen следующим образом:Выход из оболочки bash, которая была запущена с Popen?

p = Popen('"my/windows/path/to/bash.exe" | git clone or other commands') 
p.wait() 

Проблема в том, что после того, как Баш выполняет команды ввода трубы в он, он не закрывается. Он остается открытым, заставляя мой wait блокировать бесконечно.

Я попытался набросать команду «exit» в конце, но это не сработает.

p = Popen('"my/windows/path/to/bash.exe" | git clone or other commands && exit') 
p.wait() 

Но все же бесконечная блокировка на ожидание. После завершения своей задачи он просто сидит в подсказке bash, ничего не делая. Как заставить его закрыть?

+1

Что с символом '|' здесь? Это не то, как вы передаете команды в bash. –

+1

Кроме того, почему вы вызываете bash вообще, а не * напрямую * вызываете свои команды git из Python? Прямой маршрут упрощает обработку сигналов - это означает, что вы можете легко проверить статус или убить команду git самостоятельно, вместо того, чтобы иметь только дескриптор оболочки bash и не знать, что git (или другие подпроцессы под ним) делает. –

+0

@CharlesDuffy это то, как вы выполняете команды в bash – Calum

ответ

1

Попробуйте Popen.terminate() Это может помочь убить ваш процесс. Если у вас есть только синхронные команды выполнения, попробуйте использовать их непосредственно с subprocess.call().

, например

import subprocess 
subprocess.call(["c:\\program files (x86)\\git\\bin\\git.exe", 
        "clone", 
        "repository", 
        "c:\\repository"]) 
0 

Ниже приведен пример использования трубы, но это немного усложненной для большинства случаев использования и имеет смысл только в том случае, когда вы говорите с сервисом, который необходимо взаимодействие (по крайней мере, на мой взгляд).

p = subprocess.Popen(["c:\\program files (x86)\\git\\bin\\git.exe", 
         "clone", 
         "repository", 
         "c:\\repository"], 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE 
        ) 
print p.stderr.read() 
fatal: destination path 'c:\repository' already exists and is not an empty directory. 
print p.wait(
128 

Это может быть применен к SSH, а также

+0

'p.terminate()' помогло бы, да, но, учитывая приведенное здесь использование, вы также можете обратиться к _why_, команды всегда висят. 'subprocess.call()', напротив, всегда будет зависать, если 'p.wait()' делает. –

0

Чтобы убить дерево процесса, вы могли бы use taskkill command on Windows:

Popen("TASKKILL /F /PID {pid} /T".format(pid=p.pid)) 

Как @Charles Duffy said, ваше использование Баш неправильно.

Чтобы выполнить команду с помощью Баш, используйте -c параметр:

p = Popen([r'c:\path\to\bash.exe', '-c', 'git clone repo']) 

В простых случаях можно использовать subprocess.check_call вместо Popen().wait():

import subprocess 

subprocess.check_call([r'c:\path\to\bash.exe', '-c', 'git clone repo']) 

Последняя команда вызывает исключение, если bash процесс возвращает ненулевой статус (он указывает на ошибку).

Смежные вопросы