Может ли программа на C генерировать и вызывать bashscript в фоновом режиме и даже анализировать аргументы? - PullRequest
0 голосов
/ 25 марта 2012

Может ли программа на C генерировать bashscript и использовать некоторые аргументы из программы C для синтаксического анализа аргументов для запуска bashscript в фоновом режиме (без уведомления пользователя, если это действительно под землей, это невозможно), поэтому я могу использовать некоторые "крутые"функции Bashscript, чтобы сделать некоторую работу в "C"?Мне нужен результат возвращения bashscript в программу на Си.

Спасибо за любой совет.

Ответы [ 5 ]

2 голосов
/ 25 марта 2012

Используйте fork(), чтобы создать «клон» вашего процесса.

Если вы хотите получить результаты от bash (или любой другой команды, которую вы будете выполнять), используйте pipe() и dup() для созданиясоединение между процессами из стандартного вывода (и стандартной ошибки, если вы тоже этого хотите) команды exec'd.Ваш процесс сможет читать (и писать, если вы создадите больше каналов) exec'd программ, выводящих текст.

Обычно процесс 'клонирования' либо использует dup() для повторного подключения стандартного ввода / вывода / ошибки к каналам, либо закрывает стандартный стандартный ввод / вывод / ошибку, чтобы предотвратить взаимодействие программы exec'd с пользователем.

Затем используйте одну из форм exec().

Если ваш процесс не wait(), процесс exec'd будет запускаться «в фоновом режиме»на самом деле одновременно.Эффект нахождения в фоновом режиме в основном является результатом отключения от терминала (клавиатура и окно).

Если каналы настроены правильно, ваша программа сможет взаимодействовать с процессом fork + exec'd, но получить тупиковую блокировку легко, поэтому я предлагаю вам ограничить себя чтением еевыход.

1 голос
/ 25 марта 2012

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

1 голос
/ 25 марта 2012

Может помочь функция стандартной библиотечной системы ().Пример может выглядеть следующим образом:

#include <stdlib.h>

int main( void ){
    int scriptResult;
    scriptResult = system("myscript.sh");
    return 0;
}

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

1 голос
/ 25 марта 2012

Команда system() может выполнить эту работу, если вы укажете параметр & для процесса scipt.

Аргумент system() должен быть командой, которую вы хотите выполнить, так же, как если бы вы выполняли ее из bash. В этом случае это будет script.sh &, где & указывает операционной системе запускать процесс в фоновом режиме.

Обратите внимание, что использование system зависит от операционной системы и может быть небезопасным, поэтому используйте его соответствующим образом.

0 голосов
/ 25 марта 2012

Рабочий пример на Linux. замените / bin / bash на свое собственное местоположение bash

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <assert.h>
#include <sys/wait.h>

int plumbing( const char * work, char * results, size_t so_results) {
        int p1[2],p2[2];
        pid_t pid,pidw;
        void (*old)(int);
        int bytes,cnt,status,rc;
        char * bash[2] = {"/bin/bash",0};
        old=signal(SIGCHLD,SIG_DFL);
        rc = pipe(p1); if(rc){perror("pipe()");return -1;}
        rc = pipe(p2); if(rc){perror("pipe()");return -1;}
        pid = fork();
        if (pid<0) { perror("fork"); return -1;}
        if (0 == pid) {
                rc = dup2(p1[0],0); if (-1 == rc) {perror("dup2"); return -1;}
                rc = dup2(p2[1],1); if (-1 == rc) {perror("dup2"); return -1;}
                close(p1[1]); close(p2[0]);
                rc = execvp(bash[0],bash);
                if (-1 == rc) {perror("execvp"); return -1;} exit(-1);
        }
        close(p1[0]);close(p2[1]);
        write(p1[1],work,strlen(work));
        cnt = 0;
        close(p1[1]);
        bytes = read(p2[0],results,so_results);
        while(bytes > 0) {
                cnt+=bytes;
                if (so_results== cnt) break;
                bytes = read(p2[0],results+cnt,so_results-cnt);
        }
        if (cnt == so_results) {
                char dummy[4096];
                bytes = read(p2[0],dummy,4096);
                while (bytes>0) {
                        bytes = read(p2[0],dummy,4096);
                }
        }
        pidw = waitpid(pid,&status,WCONTINUED|WUNTRACED);
        if (pidw != pid || status !=0 ) { perror("waitpid"); return -1;}
        signal(SIGCHLD,old);
        return 0;
}
int main() {
        int rc;
        char buffer[4096];
        rc = plumbing(
"t=$(cat<< @@@\n"
"ICAgICAgIGE4ODg4Yi4KICAgICAgZDg4ODg4OGIuCiAgICAgIDhQIllQIlk4OAogICAgICA4fG98fG98\n"
"ODgKICAgICAgOCcgICAgLjg4CiAgICAgIDhgLl8uJyBZOC4KICAgICBkLyAgICAgIGA4Yi4KICAgIGRQ\n"
"ICAgLiAgICBZOGIuCiAgIGQ4OicgICIgIGA6Ojg4YgogIGQ4IiAgICAgICAgICdZODhiCiA6OFAgICAg\n"
"JyAgICAgIDo4ODgKICA4YS4gICA6ICAgICBfYTg4UAouXy8iWWFhXzogICAufCA4OFB8ClwgICAgWVAi\n"
"ICAgIGB8IDhQICBgLgovICAgICBcLl9fXy5kfCAgICAuJwpgLS0uLl9fKTg4ODhQYC5fLicK\n"
"@@@)\n"
"r64=\'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\'\n"
"i=0; while [ $i -lt 256 ] ; do tab[$i]=-1 ; let i=$i+1 ;done\n"
"i=0; while [ $i -lt 64 ] ; do tab[`printf \"%d\" \"\'${r64:$i:1}\"`]=$i ; let i=$i+1; done\n"
"bi=0\n"
"i=0 \n"
"while ((i < ${#t} )) \n"
"  do\n"
"   x=${t:$i:1}\n"
"   in=${tab[`printf \"%d\" \"\'$x\"`]}\n"
"   if [ $in -ge 0 ]; then case $bi in\n"
"    0 ) out=$(($in<<2)); bi=6 ;;\n"
"    2 ) out=$(($out|$in)); printf \\\\$(printf \'%03o\' $(($out&255)) ); bi=0 ;;\n"
"    4 ) out=$(($out+($in>>2))); printf \\\\$(printf \'%03o\' $(($out&255)) );\n"
"    bi=0; out=$(($in<<6)); bi=2 ;;\n"
"    * ) out=$(($out+($in>>4))); printf \\\\$(printf \'%03o\' $(($out&255)) );\n"
"    bi=0; out=$(($in<<4)); bi=4 ;;\n"
"    esac fi\n"
"   i=$((1+$i))\n"
"  done\n"
        ,buffer,4096);
        printf("plumbing rc %d\n",rc);
        printf("%s", buffer);
}
...