#c #linux #process
#c #linux #процесс
Вопрос:
У меня есть простая программа, написанная на C с использованием функции system () в Ubuntu 12.04 следующим образом:
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("getpid() = %dn", getpid());
printf("getppid() = %dn", getppid());
printf("cmd process ID:n");
system("echo $BASHPID");
return 0;
}
и запустил ее с помощью gcc в терминале, что дало следующие результаты.
$ gcc -o exmpl_bashpid exmpl_bashpid.c
$ ./exmpl_bashpid
getpid() = 2892
getppid() = 2060
cmd process ID:
$
мой вопрос в том, что функция system («echo $ BASHPID») ничего не даст. когда я попытался использовать некоторые распространенные команды, такие как date, она выдает в терминале при запуске исполняемого файла. Только этот приведенный выше случай не дает надлежащих результатов. Какое может быть возможное объяснение? Я меньше всего знаком с процессами Linux и системными вызовами в программировании на C. Любая информация будет полезна для моего дальнейшего изучения. Спасибо.
Комментарии:
1. Почему именно вы спрашиваете? Я предполагаю, что извлечение
BASHPID
из программы на C — неправильный способ достижения вашей цели.2. @BasileStarynkevitch, мне нужно знать, действительно ли system () создаст другой процесс или нет, просто зная его идентификатор процесса.
3. Чтобы получить идентификатор процесса оболочки, используйте
echo $$
который намного более переносим и не являетсяbash
специфичным.
Ответ №1:
system
работает нормально /bin/sh
и, предположительно, это не устанавливается $BASHPID
. Попробуйте использовать:
system("/bin/bash -c 'echo $BASHPID'")
Обратите внимание, что при этом всегда будет выводиться только PID дочернего процесса bash, вызываемого system
, что не очень полезно. Похоже, вы пытаетесь получить PID родительского процесса bash, который не будет работать, поскольку BASHPID
переменная родительского bash не экспортируется, поскольку ввод
/bin/sh -c 'echo $BASHPID'
в командной строке будет продемонстрировано.
Комментарии:
1. Если я изменю приведенный выше код, как вы предложили, он выдаст другой PID для каждого случая. Использую ли я здесь 3 процесса, включая shell в качестве одного из них? если да, то / bin / bash выполнит какой-либо другой процесс?
2. Ну, system () запускает новый процесс, поэтому они, скорее всего, получат другой pid
Ответ №2:
Чтобы получить переменную среды внутри программы на C, используйте getenv(3).
Итак, если вы считаете, что ваша программа запускается в среде, которая BASHPID
задана (т. Е. export
отредактирована в bash), попробуйте:
int bashpid = 0;
char*bashpidstr = getenv("BASHPID");
if (bashpidstr amp;amp; isdigit(bashpidstr[0]))
bashpid = atoi(bashpidstr);
Однако довольно часто оболочка является родительским процессом, к которому вы можете запросить с помощью getppid(2). Или это руководитель группы процессов, см. getpgid(2)
Если вы хотите получить вывод какой-либо команды, используйте popen(3), например
int bashpid = 0;
FILE* cmd = popen("echo $BASHPID", "r");
if (cmd) { fscanf(cmd, "%d", amp;bashpid); pclose(cmd); }
else { perror("popen"); exit(EXIT_FAILURE); }
Но это, вероятно, не будет работать так, как вы хотите, поскольку popen
или system
может возникнуть форк /bin/sh
a bash
, который может быть a, и, возможно, вам следует echo $$
Кроме того, BASHPID специфичен для bash
. Моя интерактивная оболочка (для входа) — zsh, поэтому она не будет установлена.
Обратите внимание, что обычно вам следует вызывать fflush(3) (например fflush(NULL);
…) перед любой функцией разветвления, такой как popen
или system
, чтобы убедиться, что буферы stdio очищены.
дополнения
Если вы хотите знать, создает ли system (3) другой процесс, прочитайте его документацию:
Библиотечная функция system() использует fork(2) для создания дочернего процесса, который выполняет команду оболочки, указанную в command, используя execl(3) следующим образом:
execl("/bin/sh", "sh". "-c", command, (char *) 0);
system() возвращается после завершения команды.
Однако существует особый случай, если вы передаете NULL
аргумент в system
:
Если команда равна нулю, то system() возвращает статус, указывающий, доступна ли оболочка в системе
Кроме того, изучите исходный код некоторой реализации, например, process / system.c из musl-libc
Комментарии:
1. BASHPID не будет отправлен в программу C, поскольку он не экспортирован (насколько я могу судить)