Найти - Пользователи
Полная версия: питон + cmd с аргументами
Начало » Python для новичков » питон + cmd с аргументами
1 2
xam1816
Pacifist
Буду пробовать
а картинки эта программа показывает какие нибудь? скачал посмотреть,какие-то цифры ,буквы идут,а кина нет,файлы .fds взял из папки Examples
Pacifist
Pacifist
пример как раз для меня) спасибо! Именно эту команду мне нужно запустить, отредактировав индексы и имя файла в питоне.
Буду пробовать
поторопился, на холодную такое не запустилось
 import os
from subprocess import Popen, PIPE
# changes directory to directory where input file is saved.
base = (os.getcwd())
string = rf"{base}\1"
os.chdir(string)
cmd = 'cmd.exe'
p = Popen(cmd, stdin=PIPE, stdout=PIPE, bufsize=0, shell=True)
p.stdin.write(rb"fdsinit\b_1")
p.stdin.write(b"fds_local -p 2 -o 2 b_1.fds")
p.stdin.close()
p.wait()

PEHDOM
зачем? ставите условие если нет аргументов то просто батник работает как есть, если есть аргумент парсите его
типа
что бы попробовать это, нужно чуть больше времени)
xam1816
Pacifist
поторопился, на холодную такое не запустилось
Покажите пример что нужно сделать,т.е какая последовательность действий должна сработать,
Запускаю файл.fds идут какие то тесты ,что должно быть в конце?
…….
И вопрос всем:
Возможно ли запустить процесс типа
 cmd = 'cmd.exe'
p = Popen(cmd, stdin=PIPE, stdout=PIPE, bufsize=0, shell=True)
Как-то отследить что команда выполнилась без ошибок,передав в переменную код завершения
Если код==0 (к примеру)
Потом передать строку
Снова отследить выполнилась ли без ошибок или узнать что выполняется
Если закончилось выполнение достать нужные данные
Снова ввести следующую строку
Снова отслеживать и ТД.
Т.е как сделать такую автоматизацию?Есть какой-нибудь пример?
Pacifist
xam1816
а картинки эта программа показывает какие нибудь? скачал посмотреть,какие-то цифры ,буквы идут,а кина нет,файлы .fds взял из папки Examples
C:\Program Files\firemodels\SMV6\smokeview.exe
запускает визуализацию результатов - дальше через контекстное меню
https://pyrosim.ru/polevaya-model-pozhara - здесь графическая оболочка для создания моделей и запуска расчетов (можно месяц бесплатно поюзать)

xam1816
Покажите пример что нужно сделать,т.е какая последовательность действий должна сработать,
Запускаю файл.fds идут какие то тесты ,что должно быть в конце?
решил сделать форму, потом exe-шник, что бы запускать было чуть удобнее (+ практика по питону)
Последовательность такая:
1 - запустить C:\Windows\System32\cmd.exe /k fdsinit
2 - перейти в папку с файлом .fds
3 - запустить команду вида fds_local -p 2 -o 2 name.fds (где индексы цифровые и имя соответственно меняются каждый раз - вводятся из формы)
UI
 from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(600, 320)
        MainWindow.setMinimumSize(QtCore.QSize(600, 320))
        MainWindow.setMaximumSize(QtCore.QSize(600, 320))
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.widget = QtWidgets.QWidget(self.centralwidget)
        self.widget.setGeometry(QtCore.QRect(10, 10, 581, 301))
        self.widget.setObjectName("widget")
        self.gridLayout = QtWidgets.QGridLayout(self.widget)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setObjectName("gridLayout")
        self.label_4 = QtWidgets.QLabel(self.widget)
        self.label_4.setObjectName("label_4")
        self.gridLayout.addWidget(self.label_4, 7, 0, 1, 2)
        self.label_okORno = QtWidgets.QLabel(self.widget)
        self.label_okORno.setText("")
        self.label_okORno.setAlignment(QtCore.Qt.AlignCenter)
        self.label_okORno.setObjectName("label_okORno")
        self.gridLayout.addWidget(self.label_okORno, 2, 0, 1, 1)
        self.toolButton_fds = QtWidgets.QToolButton(self.widget)
        self.toolButton_fds.setObjectName("toolButton_fds")
        self.gridLayout.addWidget(self.toolButton_fds, 1, 1, 1, 1)
        self.toolButton_file = QtWidgets.QToolButton(self.widget)
        self.toolButton_file.setObjectName("toolButton_file")
        self.gridLayout.addWidget(self.toolButton_file, 4, 1, 1, 1)
        self.lineEdit_fds = QtWidgets.QLineEdit(self.widget)
        self.lineEdit_fds.setObjectName("lineEdit_fds")
        self.gridLayout.addWidget(self.lineEdit_fds, 1, 0, 1, 1)
        self.lineEdit_file = QtWidgets.QLineEdit(self.widget)
        self.lineEdit_file.setObjectName("lineEdit_file")
        self.gridLayout.addWidget(self.lineEdit_file, 4, 0, 1, 1)
        self.label_3 = QtWidgets.QLabel(self.widget)
        self.label_3.setObjectName("label_3")
        self.gridLayout.addWidget(self.label_3, 5, 0, 1, 2)
        self.label_2 = QtWidgets.QLabel(self.widget)
        self.label_2.setObjectName("label_2")
        self.gridLayout.addWidget(self.label_2, 3, 0, 1, 1)
        self.label = QtWidgets.QLabel(self.widget)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
        self.pushButton_run = QtWidgets.QPushButton(self.widget)
        self.pushButton_run.setObjectName("pushButton_run")
        self.gridLayout.addWidget(self.pushButton_run, 9, 0, 1, 2)
        self.spinBox_p = QtWidgets.QSpinBox(self.widget)
        self.spinBox_p.setProperty("value", 4)
        self.spinBox_p.setObjectName("spinBox_p")
        self.gridLayout.addWidget(self.spinBox_p, 6, 0, 1, 2)
        self.spinBox_o = QtWidgets.QSpinBox(self.widget)
        self.spinBox_o.setProperty("value", 1)
        self.spinBox_o.setObjectName("spinBox_o")
        self.gridLayout.addWidget(self.spinBox_o, 8, 0, 1, 2)
        MainWindow.setCentralWidget(self.centralwidget)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "RUN FDS"))
        self.label_4.setText(_translate("MainWindow", "Количество потоков/количесвто o-"))
        self.toolButton_fds.setText(_translate("MainWindow", "..."))
        self.toolButton_file.setText(_translate("MainWindow", "..."))
        self.label_3.setText(_translate("MainWindow", "Количество сеток/количесвто p-"))
        self.label_2.setText(_translate("MainWindow", "Абсолютный путь к файлу"))
        self.label.setText(_translate("MainWindow", "Абсолютный путь к папке установки fds"))
        self.pushButton_run.setText(_translate("MainWindow", "Запуск"))

моя форма (сырая, много багов):
 import os
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QTableWidgetItem, QFileDialog
from UI.fds import Ui_MainWindow
import sys
import subprocess
class MyWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MyWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setWindowIcon(QIcon('run.PNG'))
        self.ui.label_okORno.hide()
        self.path_file = ''
        self.count_p = 4
        self.count_o = 1
        self.files_fds = os.listdir(r'C:\Program Files')
        if 'firemodels' in self.files_fds:
            self.ui.label_okORno.show()
            self.ui.label_okORno.setStyleSheet("background-color:green; border-radius:5px")
            self.ui.label_okORno.setText('Необходимые для расчета файлы fds имеются')
        else:
            self.ui.label_okORno.show()
            self.ui.label_okORno.setStyleSheet("background-color:red; border-radius:5px")
            self.ui.label_okORno.setText('Программа fds не найдена. Выберете папку /firemodels/')
        self.run = 'fds_local -p 1 -o 1 job_name.fds'
        self.run_cmd1 = 'C:\Windows\System32\cmd.exe'
        self.run_cmd2 = '/k fdsinit'
        self.ui.toolButton_file.clicked.connect(self.showDialogOpen_file)
        self.ui.toolButton_fds.clicked.connect(self.showDialogOpen_fds)
        self.ui.spinBox_p.valueChanged.connect(self.updateLabel_p)
        self.ui.spinBox_o.valueChanged.connect(self.updateLabel_o)
        self.ui.pushButton_run.clicked.connect(self.runFds)
    def updateLabel_p(self, value):
        self.count_p = value
    def updateLabel_o(self, value):
        self.count_o = value
    def showDialogOpen_fds(self):
        fname = QFileDialog.getExistingDirectory()
        path_fds = fname
        self.ui.lineEdit_fds.setText(path_fds)
        self.files_fds = os.listdir(path_fds)
        if 'FDS6' in self.files_fds:
            self.ui.label_okORno.show()
            self.ui.label_okORno.setStyleSheet("background-color:green; border-radius:5px")
            self.ui.label_okORno.setText('Необходимые для расчета файлы fds имеются')
        else:
            self.ui.label_okORno.show()
            self.ui.label_okORno.setStyleSheet("background-color:red; border-radius:5px")
            self.ui.label_okORno.setText('Программа fds не найдена')
    def showDialogOpen_file(self):
        fname = QFileDialog.getOpenFileName(filter='*.fds')
        self.path_file = fname[0]
        self.ui.lineEdit_file.setText(self.path_file)
    def runFds(self):
        if self.ui.label_okORno.text() == 'Необходимые для расчета файлы fds имеются' and self.path_file[-3:] == 'fds':
            fds = self.path_file.split("/")
            vv = f'fds_local -p {self.count_p} -o {self.count_o} {fds[-1]}'
            # run_cmd = f'{self.run_cmd1} {vv} {self.run_cmd2}'
            cd = 'cd..'
            run_cmd = f'{self.run_cmd1} {self.run_cmd2}'
            # subprocess.call('cmd.exe && cd..', shell=True)
            subprocess.run(f'{run_cmd} | /k cd..', shell=True)
            # os.system(run_cmd)
        else:
            QtWidgets.QMessageBox.information(self, "ВНИМАНИЕ!", 'Вы не выбрали файл .fds или отсутствует программа fds')
xam1816
вот что-то типа такого
 from subprocess import Popen,PIPE,STDOUT
def run_fds_local(options='',):
	start = ['cmd','/k','fdsinit']
	p = Popen(start, stdin=PIPE, stdout=PIPE, stderr = STDOUT, universal_newlines=True)
	out = p.communicate(input=f'fds_local {options}\n')
	return out
res = run_fds_local('-v')
print(res[0])

вывод
 type helpfds for help on running fds
(venv) D:\programming\telegramm_bot>fds_local -v
 Fire Dynamics Simulator
 Current Date     : October 19, 2021  12:23:49
 Revision         : FDS6.7.6-0-g5064c500c-release
 Revision Date    : Thu May 27 12:19:10 2021 -0400
 Compiler         : Intel ifort 2021.1
 Compilation Date : Tue 06/01/2021  11:25 AM
 MPI Enabled;    Number of MPI Processes:       1
 OpenMP Enabled; Number of OpenMP Threads:      1
 MPI version: 3.1
 MPI library version: Intel(R) MPI Library 2021.1 for Windows* OS
 Consult FDS Users Guide Chapter, Running FDS, for further instructions.
(venv) D:\programming\telegramm_bot>
Process finished with exit code 0
Pacifist
xam1816
вот что-то типа такого
спасибо, это работает, но..
информация выведется только после окончания расчета, а это может занимать не один день
при запуске из cmd выдается в консоль нужная информация прогресса, ошибки, окончание.
subprocess может запустить cmd в данном контексте как строннее приложение, а не внутри себя?
Или можно получать каждое изменения?




Pacifist
xam1816
вот что-то типа такого
Сначала со скепсисом отнесся к способу запускать расчет внутри питона, а не через стандартную сmd.
Спарсив данные, которые показаны на скрине, можно еще много всего автоматизировать.
Этими двумя функциями я запускаю расчет, но во время расчета пустое окно и ход расчета вываливается только по окончании.
     def run_fds_local(self, options, path):
        # base = (os.getcwd())
        os.chdir(path)
        start = ['cmd', '/k', 'fdsinit']
        p = Popen(start, stdin=PIPE, stdout=PIPE, stderr=STDOUT, universal_newlines=True)
        print(p)
        # p = Popen(start, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
        out = p.communicate(input=f'fds_local {options}\n')
        print(out)
        return out
    def runFds(self):
        if self.ui.label_okORno.text() == 'Необходимые для расчета файлы fds имеются' and self.path_file[-3:] == 'fds':
            fds = self.path_file.split("/")
            path = '/'.join(self.path_file.split("/")[:-1])
            self.run_fds_local(f'-p {self.count_p} -o {self.count_o} {fds[-1]}', path)
        else:
            QtWidgets.QMessageBox.information(self, "ВНИМАНИЕ!", 'Вы не выбрали файл .fds или отсутствует программа fds')

Реально получить данные расчета по мере поступления данных?
Не очень понимаю от чего это зависит и что нужно гуглить.
xam1816
Pacifist
Реально получить данные расчета по мере поступления данных?
Да реально, надо только разобраться с PIPE и stdout,пока изучаю,для меня это новое направление
xam1816
Идея такая, вывод записывать в файл,причем в отдельном потоке
между делом можно в файл залазить и чего нибудь брать от туда
в примере задержка - это типа долгая обработка из fds_local
а функция read_file() проверяет есть ли новая строка через 0.5 секунды

 from subprocess import Popen,PIPE,STDOUT
from threading import Thread
import time
import random
def run_fds_local(options=''):
	start = ['cmd','/k','fdsinit']
	with open('temp_data.txt','w') as f:
		p = Popen(start, stdin=PIPE, stdout=f,bufsize=0, stderr = STDOUT, universal_newlines=True)
		p.stdin.write(f'fds_local {options}\n')
		time.sleep(5)
		f.write('end')
def read_file():
	with open('temp_data.txt', 'r') as f:
		while True:
			line = f.readline()
			if line:
				print(line)
				if line == 'end':
					break
			else:
				time.sleep(0.5)
if __name__ == '__main__':
	fds_loc = Thread(target=run_fds_local,kwargs={'options':'-v'})
	fds_loc.start()
	
	read_file()
	fds_loc.join()
Pacifist
xam1816
Идея такая, вывод записывать в файл,причем в отдельном потоке
между делом можно в файл залазить и чего нибудь брать от туда
в примере задержка - это типа долгая обработка из fds_local
а функция read_file() проверяет есть ли новая строка через 0.5 секунды

Программа закончила выполнение кода (почти сразу) - напечатано end
А в фоне идет расчет (в диспетчере задач)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB