Good afternoon, you need to run a python script that sends data as a print to the console and read this data in a C program.
Sort of:
char buf[256]; start ("python foo.py", &buf); Where buf is the entire output of the script.
Good afternoon, you need to run a python script that sends data as a print to the console and read this data in a C program.
Sort of:
char buf[256]; start ("python foo.py", &buf); Where buf is the entire output of the script.
#include <stdio.h> int main() { FILE * uname; char os[80]; int lastchar; uname = popen("uname -o", "r"); lastchar = fread(os, 1, 80, uname); os[lastchar] = '\0'; printf("Your OS is %s", os); pclose(uname); return 0; }
PS uname -o displays the name of the OS in Linux.
For Windows, there is an analogue popen :
FILE *_popen(const char *command,const char *mode); Options:
command is an executable command, mode is the state of the returned expression.
Values mode :
"r" - The calling process can read the standard output of the spawned command using the returned stream.
"w" - The calling process can write to the standard input of the child command using the return stream.
"b" - Open in binary mode.
"t" - Open in text mode.
#include <stdio.h> #include <stdlib.h> int main( void ) { char psBuffer[128]; FILE *pPipe; if( (pPipe = _popen( "dir *.c /on /p", "rt" )) == NULL ) exit( 1 ); /* Read pipe until end of file, or an error occurs. */ while(fgets(psBuffer, 128, pPipe)) { printf(psBuffer); } /* Close pipe and print return value of pPipe. */ if (feof( pPipe)) { printf( "\nProcess returned %d\n", _pclose( pPipe ) ); } else { printf( "Error: Failed to read the pipe to the end.\n"); } }
Unfortunately, there is no way to check the code.
In Unix, your problem can be solved as follows:
* All the nuances regarding the use of system calls can be searched in mana, or, for example, look in the books of Stevens.
I'll add 5 more kopecks to the Linux solutions.
Use forkpty to get the link to the command being run. The essential difference from the previous options is that we get a bidirectional "terminal-like" ( pty ) connection. In principle, this way (well, by adding something to the pseudo-terminal control) you can simulate a real dialogue with any program (for example, vi (?)), Although it is most applicable for su / ssh, etc., refusing to read the password not from the terminal (but not only, because generally, the behavior of FILE * depends on whether it works with a terminal or a file, pipe, etc.).
Of course, within the framework of this question, such opportunities are redundant, but still ...
// compile gcc (or g++) with -lutil // Запустим переданные аргументы командной строки, как команду // и напечатаем ее stdout/stderr, // а затем выведем результат ее работы (код возврата) #include <stdio.h> #include <unistd.h> #include <pty.h> #include <err.h> #include <sysexits.h> #include <sys/wait.h> int main (int ac, char *av[]) { int tty; pid_t child = forkpty(&tty, 0, 0, 0); // в этой точке у нас работают (надеемся!) уже два процесса (один запущен внутри forkpty) // поэтому проявите особое внимание к вставке сюда какого-то кода switch (child) { case -1: err(EX_OSERR, "forkpty"); // never Returns case 0: // эта часть switch исполняется в "дочернем" процессе!!! // запустим команду, которая будет писать в наш tty execvp(av[1], &av[1]); // при успешном вызове возврата не будет err(EX_UNAVAILABLE, "execvp"); // never Returns } // а здесь уже наверняка опять один процесс (исходный "папа") char *str = 0; size_t ssz; FILE *in = fdopen(tty, "r"); // привяжем к tty FILE while (getline(&str, &ssz, in) != EOF) // getline() еще одна удобная GNU штучка fputs(str, stdout); fclose(in); // tty закроется здесь int s, rc; wait(&s); // мы запускали один процесс и ждем его завершения, так что можно не изгаляться с waitpid/wait3 и т.п. // корректная обработка всех возможных ситуаций немного длинее, для простоты опустим их const char *msg = WIFEXITED(s) ? "exited with code" : "terminated by signal"; rc = *msg == 'e' ? WEXITSTATUS(s) : WTERMSIG(s); printf("---- %s (%ld) %s %d ----\n", av[1], (long)child, msg, rc); return puts("End") == EOF; } Now run and see:
avp@avp-xub11:hashcode$ g++ -Wall tc -lutil ; ./a.out ls -alR /tmp /tmp: total 32 drwxrwxrwt 6 root root 4096 Nov 2 13:08 . drwxr-xr-x 24 root root 4096 Oct 20 15:07 .. -rw------- 1 avp avp 0 Oct 29 13:35 config-err-TwtmYo drwx------ 2 avp avp 4096 Oct 29 13:36 .esd-1000 drwx------ 2 lightdm lightdm 4096 Oct 29 13:36 .esd-104 drwxrwxrwt 2 root root 4096 Oct 29 13:35 .ICE-unix -r--r--r-- 1 root root 11 Oct 29 13:34 .X0-lock drwxrwxrwt 2 root root 4096 Oct 29 13:34 .X11-unix -rw------- 1 avp avp 418 Oct 29 13:35 .xfsm-ICE-NLCL7X /tmp/.esd-1000: total 8 drwx------ 2 avp avp 4096 Oct 29 13:36 . drwxrwxrwt 6 root root 4096 Nov 2 13:08 .. srwxrwxrwx 1 avp avp 0 Oct 29 13:36 socket ls: cannot open directory /tmp/.esd-104: Permission denied /tmp/.ICE-unix: total 8 drwxrwxrwt 2 root root 4096 Oct 29 13:35 . drwxrwxrwt 6 root root 4096 Nov 2 13:08 .. srwxrwxrwx 1 avp avp 0 Oct 29 13:35 2019 /tmp/.X11-unix: total 8 drwxrwxrwt 2 root root 4096 Oct 29 13:34 . drwxrwxrwt 6 root root 4096 Nov 2 13:08 .. srwxrwxrwx 1 root root 0 Oct 29 13:34 X0 ---- ls (14744) exited with code 2 ---- End avp@avp-xub11:hashcode$ avp@avp-xub11:hashcode$ ./a.out hjsdjhdj a.out: execvp: No such file or directory ---- hjsdjhdj (14783) exited with code 69 ---- End avp@avp-xub11:hashcode$ Source: https://ru.stackoverflow.com/questions/463121/
All Articles