Вызов внешней команды в Python
blockquote>Простой, используйте
subprocess.run
, который возвращает объектCompletedProcess
:>>> import subprocess >>> completed_process = subprocess.run('python --version') Python 3.6.1 :: Anaconda 4.4.0 (64-bit) >>> completed_process CompletedProcess(args='python --version', returncode=0)
Почему?
Начиная с Python 3.5, в документации рекомендуется subprocess.run :
. Рекомендуемым подходом к вызову подпроцессов является использование функции run () для всех случаев использования, которые он может обрабатывать.
blockquote>Ниже приведен пример простейшего возможного использования - и он выполняет точно так же, как и задано:
>>> import subprocess >>> completed_process = subprocess.run('python --version') Python 3.6.1 :: Anaconda 4.4.0 (64-bit) >>> completed_process CompletedProcess(args='python --version', returncode=0)
run
ждет завершения команды, а затем возвращает объектCompletedProcess
. Он может вместо этого подниматьTimeoutExpired
(если вы дадите ему аргументtimeout=
) илиCalledProcessError
(если он терпит неудачу и вы пройдетеcheck=True
).Как вы могли бы сделать вывод из приведенного выше примера, stdout и stderr оба по умолчанию передаются по вашему собственному stdout и stderr.
Мы можем проверить возвращаемый объект и увидеть команду, которая была указана, и код возврата:
>>> completed_process.args 'python --version' >>> completed_process.returncode 0
Захват output
Если вы хотите захватить вывод, вы можете передать
subprocess.PIPE
в соответствующиеstderr
илиstdout
:>>> cp = subprocess.run('python --version', stderr=subprocess.PIPE, stdout=subprocess.PIPE) >>> cp.stderr b'Python 3.6.1 :: Anaconda 4.4.0 (64-bit)\r\n' >>> cp.stdout b''
(я нахожу это интересным и слегка что информация о версии попадает в stderr вместо stdout.)
Передача списка команд
Можно легко перейти от ручного предоставления командной строки (например, вопрос) к предоставлению строка построена программно. Не стройте строки программно. Это потенциальная проблема безопасности. Лучше предположить, что вы не доверяете входным данным.
>>> import textwrap >>> args = ['python', textwrap.__file__] >>> cp = subprocess.run(args, stdout=subprocess.PIPE) >>> cp.stdout b'Hello there.\r\n This is indented.\r\n'
Обратите внимание, что только
args
следует передавать по позициям.Полная подпись
Вот фактическая сигнатура в источнике и как показано на рисунке
help(run)
:blockquote>def run(*popenargs, input=None, timeout=None, check=False, **kwargs):
popenargs
иkwargs
присваиваются конструкторуPopen
.input
может быть строкой байтов (или unicode, если указать кодировку илиuniversal_newlines=True
), которые будут переданы по каналу в stdin подпроцесса.Документация описывает
timeout=
иcheck=True
лучше, чем I can:Аргумент timeout передается Popen.communicate (). Если истечет время ожидания, дочерний процесс будет убит и будет ждать. Исключение TimeoutExpired будет повторно поднято после завершения дочернего процесса.
Если проверка верна, и процесс завершается с ненулевым кодом выхода, будет вызвано исключение CalledProcessError. Атрибуты этого исключения содержат аргументы, код выхода и stdout и stderr, если они были захвачены.
blockquote>, и этот пример для
check=True
лучше, чем один, который я мог бы придумать:blockquote>>>> subprocess.run("exit 1", shell=True, check=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
Расширенная подпись
Вот расширенная подпись, указанная в документации:
blockquote>subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None)
Обратите внимание, что это означает, что только список аргументов должен быть передан позиционно. Итак, передайте оставшиеся аргументы в качестве аргументов ключевого слова.
Popen
При использовании
Popen
вместо этого? Я бы изо всех сил пытался найти прецедент, основанный только на аргументах. Однако прямое использованиеPopen
даст вам доступ к его методам, включаяpoll
, «send_signal», «terminate» и «wait».Вот подпись
Popen
, как указано в источнике . Я думаю, что это наиболее точное инкапсулирование информации (в отличие отhelp(Popen)
):def __init__(self, args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None):
Но более информативным является документация
Popen
:subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None)
Выполнить дочернюю программу в новом процессе. В POSIX класс использует os.execvp () - подобное поведение для выполнения дочерней программы. В Windows класс использует функцию Windows CreateProcess (). Аргументы для Popen следующие.
blockquote>Понимание оставшейся документации в
Popen
будет оставлено как упражнение для читателя.
Сначала вы должны создать метод get и set на своей странице заголовка, и ваша страница заголовка будет выглядеть примерно так:
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-custom-header',
templateUrl: './custom-header.component.html',
styleUrls: ['./custom-header.component.css']
})
export class CustomHeaderComponent implements OnInit {
title : string;
constructor() { }
@Input()
set header(header_data: any) {
this.title = header_data;
}
get header() {
return this.title;
}
ngOnInit() {
}
}
После этого вам нужно передать значение из родительского компонента, чтобы создать переменную, и присвоить свой текст заголовка следующим образом:
public title = "My Title";
И использовать это имя строковой переменной для передачи значения, чтобы ваш код пользовательского интерфейса был be:
<app-custom-header [header]="title"></app-custom-header>
с помощью этого метода вы также можете передать объект, массив и многое другое. Я создал стекаблиц для вашего решения.