Форум сайта python.su
0
Для обработки данных вызываю консольное приложение. Но перед вызовом хотелось бы убедиться, что это приложение присутствует в PATH. Пришел к такому решению
def appInstalled(): myPath = utils.getPath() res = 1 fnull = open( os.devnull, "w" ) try: res = subprocess.call( myPath, stdout = fnull, stderr = fnull ) except: pass finally: fnull.close() if res == 0: return True else: return False
res = subprocess.call( myPath, stdout = fnull, stderr = fnull )Что делаю не так, в чем ошибка? Может, есть другие кроссплатформенные способы проверить наличие исполнимого файла в PATH?
File “C:\Python27\lib\subprocess.py”, line 493, in call
return Popen(*popenargs, **kwargs).wait()
File “C:\Python27\lib\subprocess.py”, line 672, in __init__
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File “C:\Python27\lib\subprocess.py”, line 784, in _get_handles
p2cread = self._make_inheritable(p2cread)
File “C:\Python27\lib\subprocess.py”, line 823, in _make_inheritable
_subprocess.DUPLICATE_SAME_ACCESS)
WindowsError:
Офлайн
52
Офлайн
14
Как говорит гугл, попробуй shell=True
Вместо
if res == 0: return True else: return False
return res==0
Офлайн
20
_alexs_А не проще сразу ловить исключения при вызове?
Для обработки данных вызываю консольное приложение. Но перед вызовом хотелось бы убедиться, что это приложение присутствует в PATH

def call_app(path): try: subprocess.call(path) except Exception, ex: logging.error("Exception: {0}, Path: {1}".format(ex, path)) print_to_user "Application '{app}' does not exists!".format(app = path)
Отредактировано EBFE (Июль 11, 2012 17:05:59)
Офлайн
0
odnochlenРезультат тот же. Кроме того, использование shell=True потенциально небезопасно.
Как говорит гугл, попробуй shell=True
Офлайн
0
EBFEБыло бы проще, если бы не одно но. Предложенный вами код
А не проще сразу ловить исключения при вызове?
def call_app(path): try: subprocess.call(path) except Exception, ex: logging.error("Exception: {0}, Path: {1}".format(ex, path)) print_to_user "Application '{app}' does not exists!".format(app = path)
Отредактировано _alexs_ (Июль 11, 2012 17:24:30)
Офлайн
173
Не понял, если нужно просто проверить установлено ли приложение, чем не устраивает проверка на присутствие файла или более продвинутый вариант самодельного which из SO?
Если нужно запустить, перенаправить вывод, и не дожидаясь закрыть процесс, можно попробовать так:
import subprocess def can_execute(*args): try: process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) process.terminate() return True except OSError: return False print can_execute('ping', '127.0.0.1', '-n', '10') print can_execute('ping_pong', '127.0.0.1', '-n', '10')
True False [Finished in 0.1s]
Отредактировано reclosedev (Июль 11, 2012 20:14:42)
Офлайн
0
reclosedevТем, что для проверки на присутствие файла надо знать полный путь к этому файлу. А так, если программа может с равной вероятностью лежать в /usr/bin, /usr/local/bin/, /opt/sometool/, /opt/sometool/bin, ~/bin или еще где-нибудь, аналогично и на Win (Program Files, C:\tool или что-то еще)
Не понял, если нужно просто проверить установлено ли приложение, чем не устраивает проверка на присутствие файла
reclosedevДа вобщем-то устраивает. Просто, как мне кажется, вариант с попыткой вызова приложения немного проще и эффективнее
или более продвинутый вариант самодельного which из SO?
reclosedevУвы не работает. Точнее, из консоли Python работает, как и мой вариант из первого поста. А вот когда вызывают в GUI получаю DUPLICATE_SAME_ACCESS
Если нужно запустить, перенаправить вывод, и не дожидаясь закрыть процесс, можно попробовать так:
Офлайн
20
_alexs_добавте stdin = fnull
А вот когда вызывают в GUI
from sys import stdin, stdout, stderr
with open('stds.txt','a') as f:
f.write("in %d, out %d, err: %d\n" % (stdin.fileno(),
stdout.fileno(), stderr.fileno()))
-----
python: in 0, out 1, err: 2
pythonw: in -2, out -2, err: -2[code]
Отредактировано EBFE (Июль 11, 2012 23:21:09)
Офлайн
857
>>> import os.path >>> >>> def f(progname): ... path = os.getenv('PATH') ... for p in path.split(':'): ... if os.path.exists(os.path.join(p, progname)): ... return True ... return False ... >>> f('grep') True >>> f('grepa') False >>> f('python2.7') True >>> f('python2.6') True >>> f('python2.5') False >>>
Офлайн