Запуск sh скрипта и получениее его PID

Запуск sh скрипта и получениее его PID

02.10.2016 11:06:45 Просмотров 28 Источник

Возникла необходимость получить PID запускаемого скрипта, для того, чтобы можно было убить этот процесс при закрытии основной программы.

Но system() не возвращает PID.

Есть ли какое-нибудь решение данной проблемы?

У вопроса есть решение - Посмотреть?

https://ru.stackoverflow.com/questions/572950/%d0%97%d0%b0%d0%bf%d1%83%d1%81%d0%ba-sh-%d1%81%d0%ba%d1%80%d0%b8%d0%bf%d1%82%d0%b0-%d0%b8-%d0%bf%d0%be%d0%bb%d1%83%d1%87%d0%b5%d0%bd%d0%b8%d0%b5%d0%b5-%d0%b5%d0%b3%d0%be-pid#comment753879_572950
сначала fork() потом в дочернем процессе exec()
https://ru.stackoverflow.com/questions/572950/%d0%97%d0%b0%d0%bf%d1%83%d1%81%d0%ba-sh-%d1%81%d0%ba%d1%80%d0%b8%d0%bf%d1%82%d0%b0-%d0%b8-%d0%bf%d0%be%d0%bb%d1%83%d1%87%d0%b5%d0%bd%d0%b8%d0%b5%d0%b5-%d0%b5%d0%b3%d0%be-pid#comment753913_572950
С system() что-то мне кажется не получится. Почему именно system()? С popen() например можно попробовать.
https://ru.stackoverflow.com/questions/572950/%d0%97%d0%b0%d0%bf%d1%83%d1%81%d0%ba-sh-%d1%81%d0%ba%d1%80%d0%b8%d0%bf%d1%82%d0%b0-%d0%b8-%d0%bf%d0%be%d0%bb%d1%83%d1%87%d0%b5%d0%bd%d0%b8%d0%b5%d0%b5-%d0%b5%d0%b3%d0%be-pid#comment753936_572950
@avp подозреваю автор вызывает скрипты с &
https://ru.stackoverflow.com/questions/572950/%d0%97%d0%b0%d0%bf%d1%83%d1%81%d0%ba-sh-%d1%81%d0%ba%d1%80%d0%b8%d0%bf%d1%82%d0%b0-%d0%b8-%d0%bf%d0%be%d0%bb%d1%83%d1%87%d0%b5%d0%bd%d0%b8%d0%b5%d0%b5-%d0%b5%d0%b3%d0%be-pid#comment753947_572950
@avp С popen() я что-то, признюсь, поспешил. Нужен только пид, а не весь выход от скрипта. Возможно конечно, но можно проще.

Ответы - Запуск sh скрипта и получениее его PID / Запуск sh скрипта и получениее его PID

Является ответом!
0xdb

03.10.2016 01:42:45

С system(), кроме статуса завершения, ничего больше не получить. Надо system() заменить на свою функцию. Это только прототип, а не полностью рабочая функция. Конкретная реализация завсит от конкретных требований.

pid_t execute(char **argv)
{
     pid_t  pid;
     int    status;

     if ((pid = fork()) < 0) {
         printf("ERROR: forking child process failed\n");
         exit(EXIT_FAILURE);
     }
     else if (pid == 0) { /* child process */
          if (execvp(*argv, argv) < 0) {
              printf("ERROR: exec failed\n");
              exit(EXIT_FAILURE);
          }
     }
     else { /* parent */
         return pid);
     }
}

Что ешё не хватает:
Каждый возвращаемый PID надо собирать куда-нибудь в массив, и когда то их надо с waitpid() опрашивать, иначе процессов-сирот (orphan process) насобирается столько, что свободные PID закончатся и система подвиснет:

void gather_child(int sig)
{
    int status;
    pid_t pid = waitpid(-1, &status, WNOHANG);
    if (pid > 0) { /* remove pid from the list */ }
}

int main()
{
    signal(SIGCHLD, gather_child);
    ...
}
https://ru.stackoverflow.com/questions/572950/%d0%97%d0%b0%d0%bf%d1%83%d1%81%d0%ba-sh-%d1%81%d0%ba%d1%80%d0%b8%d0%bf%d1%82%d0%b0-%d0%b8-%d0%bf%d0%be%d0%bb%d1%83%d1%87%d0%b5%d0%bd%d0%b8%d0%b5%d0%b5-%d0%b5%d0%b3%d0%be-pid/572978#comment754333_572978
Вряд ли PID sh -c ему поможет, если он будет запускать скрипт в фоне (шелл завершится, а родителем станет /sbin/upstart --user)
https://ru.stackoverflow.com/questions/572950/%d0%97%d0%b0%d0%bf%d1%83%d1%81%d0%ba-sh-%d1%81%d0%ba%d1%80%d0%b8%d0%bf%d1%82%d0%b0-%d0%b8-%d0%bf%d0%be%d0%bb%d1%83%d1%87%d0%b5%d0%bd%d0%b8%d0%b5%d0%b5-%d0%b5%d0%b3%d0%be-pid/572978#comment754349_572978
@avp Точно. Когда-то делал, но уже забыл как. Надо в кодах порыть. Пока sh -c уберу. Спасибо за конструктивное замечание.
https://ru.stackoverflow.com/questions/572950/%d0%97%d0%b0%d0%bf%d1%83%d1%81%d0%ba-sh-%d1%81%d0%ba%d1%80%d0%b8%d0%bf%d1%82%d0%b0-%d0%b8-%d0%bf%d0%be%d0%bb%d1%83%d1%87%d0%b5%d0%bd%d0%b8%d0%b5%d0%b5-%d0%b5%d0%b3%d0%be-pid/572978#comment754356_572978
@avp А зачем при таком решении в фоне запускать? Это примерно тоже что и system() делает, только без wait().
https://ru.stackoverflow.com/questions/572950/%d0%97%d0%b0%d0%bf%d1%83%d1%81%d0%ba-sh-%d1%81%d0%ba%d1%80%d0%b8%d0%bf%d1%82%d0%b0-%d0%b8-%d0%bf%d0%be%d0%bb%d1%83%d1%87%d0%b5%d0%bd%d0%b8%d0%b5%d0%b5-%d0%b5%d0%b3%d0%be-pid/572978#comment754422_572978
Это верно. На самом деле мы просто не знаем, что и как хочет запускать ТС. Может ему надо еще и от управляющего терминала отсоединяться и создавать новую группу процессов. Но поскольку он пишет "чтобы можно было убить этот процесс при закрытии основной программы", то может можно обойтись просто killpg()
Закрыть X