Nano Hash - криптовалюты, майнинг, программирование

Изменить subprocess.Popen(команда linux) в Windows10

Я изучаю сопоставление изображений с помощью Superpoint (https://github.com/rpautrat/SuperPoint).

Я попытался запустить коды, написанные в области Использование. К сожалению, я использую этот код в Windows10 и Superpoint, написанном для Linux, поэтому у меня много ошибок... :(

В частности, https://github.com/rpautrat/SuperPoint/blob/master/superpoint/utils/stdout_capturing.py вызывает у меня критическую ошибку.

Есть часть subprocess.Popen для записи лог-файла с файловым дескриптором. Я хочу получить результат файла журнала такой же, как результат, полученный из ОС Linux.

Код ниже.... и я думаю, что команда tee не работает в Windows, поэтому эта часть вызывает ошибку.

Я надеюсь отредактировать эту часть для запуска всего кода для изучения Superpoint.

Пожалуйста, дайте мне знать решение проблемы с этим файловым дескриптором в Windows10.

Большое спасибо за вашу добрую помощь!

#!/usr/bin/env python
# coding=utf-8
from __future__ import division, print_function, unicode_literals
import os
import sys
import subprocess
from threading import Timer
from contextlib import contextmanager

'''
Based on sacred/stdout_capturing.py in project Sacred
https://github.com/IDSIA/sacred
'''


def flush():
    """Try to flush all stdio buffers, both from python and from C."""
    try:
        sys.stdout.flush()
        sys.stderr.flush()
    except (AttributeError, ValueError, IOError):
        pass  # unsupported


# Duplicate stdout and stderr to a file. Inspired by:
# http://eli.thegreenplace.net/2015/redirecting-all-kinds-of-stdout-in-python/
# http://stackoverflow.com/a/651718/1388435
# http://stackoverflow.com/a/22434262/1388435
@contextmanager
def capture_outputs(filename):
    """Duplicate stdout and stderr to a file on the file descriptor level."""
    # with NamedTemporaryFile(mode='w+') as target:
    with open(filename, 'a+') as target:
        original_stdout_fd = 1
        original_stderr_fd = 2
        target_fd = target.fileno()

        # Save a copy of the original stdout and stderr file descriptors
        saved_stdout_fd = os.dup(original_stdout_fd)
        saved_stderr_fd = os.dup(original_stderr_fd)

        tee_stdout = subprocess.Popen(
            ['tee', '-a', '/dev/stderr'], start_new_session=True,
            stdin=subprocess.PIPE, stderr=target_fd, stdout=1)
        tee_stderr = subprocess.Popen(
            ['tee', '-a', '/dev/stderr'], start_new_session=True,
            stdin=subprocess.PIPE, stderr=target_fd, stdout=2)

        flush()
        os.dup2(tee_stdout.stdin.fileno(), original_stdout_fd)
        os.dup2(tee_stderr.stdin.fileno(), original_stderr_fd)

        try:
            yield
        finally:
            flush()

            # then redirect stdout back to the saved fd
            tee_stdout.stdin.close()
            tee_stderr.stdin.close()

            # restore original fds
            os.dup2(saved_stdout_fd, original_stdout_fd)
            os.dup2(saved_stderr_fd, original_stderr_fd)

            # wait for completion of the tee processes with timeout
            # implemented using a timer because timeout support is py3 only
            def kill_tees():
                tee_stdout.kill()
                tee_stderr.kill()

            tee_timer = Timer(1, kill_tees)
            try:
                tee_timer.start()
                tee_stdout.wait()
                tee_stderr.wait()
            finally:
                tee_timer.cancel()

            os.close(saved_stdout_fd)
            os.close(saved_stderr_fd)

  • Возможно, вы захотите использовать подсистему Windows для Linux, тогда вы сможете запускать (почти) все, что предназначен для Linux, и вам не нужно беспокоиться об этих проблемах. 12.08.2020
  • Я не предпочитаю использовать WSL... Я уже пытался, но у нас есть некоторые проблемы с использованием WSL для нашей учебной среды.... 12.08.2020

Ответы:


1

Я бы выбрал эту реализацию: https://stackoverflow.com/a/17942748/5430833

Прежде всего, «tee» — это утилита Linux, если только у вас не установлен какой-либо порт. /dev/stderr также является дескриптором unix для потока вывода ошибок. Согласно этому ответу: cmd .exe, эквивалентный /dev/stdout, для записи в стандартный вывод «как файл», для Windows нет такого эквивалента дескриптора.

Если вы хотите, чтобы ваше решение было переносимым, я предлагаю придерживаться python и избегать Popen, если только вы не уверены, что запускаемый вами процесс работает на обеих платформах.

Редактировать: ладно, простите меня, я невнимательно прочитал вопрос. Итак, вам нужен какой-то процесс «демон», который будет захватывать все stdout и stderr. Если вы можете жить без вывода в консоль, я бы выбрал простое решение: закомментировать содержимое 'capture_outputs' и при загрузке вашего приложения (ваш тестовый файл или какой-то основной, перед любой код SuperPoint выполняется) перенаправить потоки:

sys.stdout = open('out.dat', 'w')

И где-то на выходе:

sys.stdout.close()

Вы можете обернуть свою логику с помощью ContextManager, чтобы в случае некоторых внутренних файлов исключений закрывались правильно.

Я полагаю, что вы также можете сделать перенаправление в «capture_outputs», но я советую сделать его простым, если мы не уверены, что он работает.

12.08.2020
  • Могу ли я попросить другой метод выполнить тот же процесс без использования Popen? Я не уверен, как я могу запустить этот дескриптор файла (или дескриптор файла в Windows) в чистом Python. 12.08.2020
  • Прежде всего, спасибо за ваш быстрый отредактированный ответ! Я прочитал ссылку, которую вы упомянули, и я думаю, что 1) нет метода, который может заменить tee в Windows, 2) также нет ничего, что могло бы заменить /dev/stdout в Windows. На мой взгляд, именно поэтому вы рекомендуете описанный выше метод открытия-закрытия. Ну, этот процесс не так важен для моего изучения, но если мне нужно описать или использовать его с коллегами, мне нужно получить информацию журнала, чтобы поделиться информацией о моя работа, и именно поэтому я хочу сохранить эту часть. 13.08.2020
  • Интересно, что проблема не только в части Popen, но и в том, что все шаги Capture_outputs вызывают проблемы в окнах, которые вы имеете в виду? 13.08.2020
  • Не сам Popen — выполнение команды, которая запускает утилиту Linux в Windows, может быть проблемой, верно? «capture_outputs» в основном касается запуска подпроцесса tee + правильного открытия/закрытия файлов. Я считаю, что если вы закомментируете весь метод и просто перенаправите stdout/stderr в начале вашего приложения, вы сможете собрать журналы (при условии, что в библиотеке нет других мест, которые не переносимы). Но это только для исследования/доказательства концепции. Вообще, возможно, библиотека не предназначена для работы в Windows, вы думали об этом? 13.08.2020
  • Я впервые использую ведение журнала с помощью stdin/out/err, особенно в Windows, поэтому я подумал, что команда tee является ключевой проблемой для использования приведенного выше кода. Конечно, я спросил автора Superpoint, и он сказал: «Да, эта библиотека создана для ОС Linux... Вот почему я пытаюсь изменить функцию capture_output и сделать так, чтобы эта библиотека хорошо работала в Windows. Когда я заблокировал функцию capture_output, она работает хорошо (иногда проблема cudnn...) 13.08.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..