В версии, опубликованной sunshinekitty под названием «Версия & lt; 3.0», вам может потребоваться указать apscheduler 2.1.2. У меня случайно была версия 3 на моей установке 2.7, поэтому я пошел:
pip uninstall apscheduler
pip install apscheduler==2.1.2
После этого он работал правильно. Надеюсь, что это поможет.
Вы хотите использовать popen
. Это дает Вам однонаправленный канал, с которым можно получить доступ к stdin и stdout программы.
popen является стандартным на современном Unix и подобной Unix ОС, которой Linux является тем :-)
Ввести
man popen
в терминале для чтения больше об этом.
Править
Ли popen
производит однонаправленные или двунаправленные каналы, зависит от реализации. В Linux и OpenBSD, popen
производит однонаправленные каналы, которые только для чтения или только для записи. На OS X, FreeBSD и NetBSD popen
производит двунаправленные каналы.
pipe(...)
, один для stdin
, один для stdout
. fork(...)
процесс.fork(...)
возвраты 0) dup (...)
каналы к stdin
/stdout
.exec[v][e]
чтобы быть запущенным файлом программы в дочернем процессе.fork
) возвращается PID ребенка) делают цикл, который читает от ребенка stdout
(select(...)
или poll(...)
, read(...)
) в буфер, пока ребенок не завершает (waitpid(...)
). stdin
если это ожидает некоторых.close(...)
каналы.Я не соглашаюсь с Nathan Fellman - другим вопросом не является дубликат этого, хотя предмет связан.
Для простой однонаправленной коммуникации, popen () достойное решение. Это бесполезно для двунаправленной связи, все же.
IMO, imjorge (Jorge Ferreira) дал большую часть ответа (80%?) для двунаправленной связи - но опущенный несколько ключевых деталей.
Если Вы не закрываете неиспользованные концы каналов, Вы не получаете разумное поведение, когда одна из программ завершается; например, ребенок мог бы читать из его стандартного входа, но если конец записи канала не будет закрыт в ребенке, это никогда не будет получать EOF (нулевые байты от чтения), потому что он все еще имеет открытый канал, и система думает, что он мог бы когда-то найти время для записи в тот канал, даже при том, что он в настоящее время подвешивается, ожидая чего-то для чтения из него.
Записи должны рассмотреть, обработать ли сигнал SIGPIPE, который дан, когда Вы пишете на канале, где нет никакого процесса считывания.
Необходимо знать о способности канала (зависимый платформы, и могли бы быть всего 4 КБ), и разработайте программы для предотвращения мертвой блокировки.
Я записал некоторый пример C код для кого-то еще некоторое время назад, который показывает, как сделать это. Здесь это для Вас:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
void error(char *s);
char *data = "Some input data\n";
main()
{
int in[2], out[2], n, pid;
char buf[255];
/* In a pipe, xx[0] is for reading, xx[1] is for writing */
if (pipe(in) < 0) error("pipe in");
if (pipe(out) < 0) error("pipe out");
if ((pid=fork()) == 0) {
/* This is the child process */
/* Close stdin, stdout, stderr */
close(0);
close(1);
close(2);
/* make our pipes, our new stdin,stdout and stderr */
dup2(in[0],0);
dup2(out[1],1);
dup2(out[1],2);
/* Close the other ends of the pipes that the parent will use, because if
* we leave these open in the child, the child/parent will not get an EOF
* when the parent/child closes their end of the pipe.
*/
close(in[1]);
close(out[0]);
/* Over-write the child process with the hexdump binary */
execl("/usr/bin/hexdump", "hexdump", "-C", (char *)NULL);
error("Could not exec hexdump");
}
printf("Spawned 'hexdump -C' as a child process at pid %d\n", pid);
/* This is the parent process */
/* Close the pipe ends that the child uses to read from / write to so
* the when we close the others, an EOF will be transmitted properly.
*/
close(in[0]);
close(out[1]);
printf("<- %s", data);
/* Write some data to the childs input */
write(in[1], data, strlen(data));
/* Because of the small amount of data, the child may block unless we
* close it's input stream. This sends an EOF to the child on it's
* stdin.
*/
close(in[1]);
/* Read back any output */
n = read(out[0], buf, 250);
buf[n] = 0;
printf("-> %s",buf);
exit(0);
}
void error(char *s)
{
perror(s);
exit(1);
}
Можно использовать системный вызов, прочитать страницу справочника для системы (3)