Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.118.29.219] |
|
Сообщ.
#1
,
|
|
|
В сишной пронрамме я пользуюсь функцией system();
system('some_command'\nA=$?); Как сделать так, чтобы эту переменную А можно было взять через getenv(), т.е. что еще нужно добавить, чтобы она появилась в переменных окружения интерпретатора, из-под которого запускается моя программа на С. Спасибо. |
Сообщ.
#2
,
|
|
|
system("export MY_ENV_VARIABLE=MY_VALUE");
no pravilnee inicializirovat' vse peremennie pri otkritiy novoy sessiy |
Сообщ.
#3
,
|
|
|
А под каким шелом прога то выполняется?
для bash system("MY_VAR=eprst; export MY_VAR"); для tc system("setenv MY_VAR eprst"); |
Сообщ.
#4
,
|
|
|
setenv(...)
|
Сообщ.
#5
,
|
|
|
Цитата В сишной пронрамме я пользуюсь функцией system(); system('some_command'\nA=$?); Как сделать так, чтобы эту переменную А можно было взять через getenv(), т.е. что еще нужно добавить, чтобы она появилась в переменных окружения интерпретатора, из-под которого запускается моя программа на С. Спасибо. Ответ очень прост - никак. Из потомка нет доступа к environment предка. То, что ты запускаешь с помощью system() исполняется шеллом, который будет потомком твой программы. Если ты в потомке взвел какие-то переменные среды, то родитель о них ничего не узнает, так как адресные пространства у процессов не пересекаются. Единственное, что ты можешь сделать, это исправить собственную среду окружения твоей проги. Это можно сделать (как правильно отметил makedonskij) с помощью setenv(). Такая переменная среды будет наследоваться всеми новыми потомками твоей програмыы (среда старых потомков не изменится ) |
Сообщ.
#6
,
|
|
|
Цитата borunov, 07.10.02, 10:26:24 Ответ очень прост - никак. Из потомка нет доступа к environment предка. То, что ты запускаешь с помощью system() исполняется шеллом, который будет потомком твой программы. Если ты в потомке взвел какие-то переменные среды, то родитель о них ничего не узнает, так как адресные пространства у процессов не пересекаются. Единственное, что ты можешь сделать, это исправить собственную среду окружения твоей проги. Это можно сделать (как правильно отметил makedonskij) с помощью setenv(). Такая переменная среды будет наследоваться всеми новыми потомками твоей програмыы (среда старых потомков не изменится ) Неправда. Инструкция ". export MY_ENV=MY_VALUE" определяет переменную окружения в процессе init. Соответственно, вся иерархия процессов данной сессии видит установленную переменную окружения |
Сообщ.
#7
,
|
|
|
2 alexsh:
Неправ как раз ты - допускаешь очень распространенную ошибку. Давай рассмотрим упрощенный пример, эквивалентный поведению init (не циклический и без навороченных конфигов) Вот смотри код ниже - он делает следующее: 1. запускает отцовский процесс 2. отец распечатывает свои переменные среды 3. отец запускает ребенка 4. отец меняет среду 5. отец распечатывает свои переменные среды 6. ребенок распечатывает свои переменные среды Цитата /*for printf(), perror()*/ #include <stdio.h> /*for putenv()*/ #include <stdlib.h> /*for fork(), sleep()*/ #include <unistd.h> /*for wait()*/ #include <sys/types.h> #include <sys/wait.h> extern char **environ; int child_stat; void print_env (header) char *header; { int i; printf ("-= \%s =-\n", header); for (i = 0; environ[i] != NULL; i++) printf("\%s\n", environ[i]); } int main (argc, argv, env) int argc; char **argv; char **env; { print_env ("Father, before environ changes"); /*Let's born a child*/ switch (fork ()) { case 0: /*Child*/ sleep (2); /*Child's and father's output do not overlap*/ print_env("Child, after father's environ changes"); break; case -1: /*Error*/ perror ("Could not fork()"); break; default: /*Father*/ putenv ("LAMER=TEST"); /* It changes "environ", but not "env"*/ print_env ("Father, after environ changes"); wait (&child_stat); /*Wait for child to terminate*/ break; } return 0; } Как нетрудно видеть после исполнения этого кода - первая и третья распечатки среды будут одинаковы, а вот вторая - будет иметь новую переменную LAMER. Это значит, что уже работающий процесс не получает никакого уведомления, если его отец меняет свою среду. Если бы я поместил в коде putenv() до вызова fork(), то ребенок имел бы уже измененную среду, так как он был бы порожден после ее изменения. Теперь объясняю, в чем твоя ошибка с init.... init - самый первый процесс в системе. Все остальные процессы стартуют из-под него и после него, образуя многоуровневую иерархию (я здесь не рассматриваю виртуальные треды ядра и т.п. вирт. процессы). Естественно, что они наследуют все его перменные среды. Потом они их, конечно могут удалять и менять в своем контексте. Поставь эксперимент - измени в своей системе файл inittab, добавив какую-нибудь переменную. Стрельни по init-у HUP-сигналом, чтоб он перечитал конфиг. И что ты видишь - изменилась в твоем текущем шелле среда? добавилась новая переменная? ну конечно нет, хоть твой шелл и потомок init-а (не сын, но правнук), до него эти изменения не дойдут. Но если init запустит что-то после твоего HUP-а, то новые процессы уже отнаследуют новую переменную среды. Кстати, init очень часто растартует процессы, которые описаны в его конфиге и по какой-то причине померли - см. например "respawn" в man-е по init. |
Сообщ.
#8
,
|
|
|
Не хочу вступать в длинную дисскуссию, просто предлагау выполнить приведенную мною выше инструкцию ". export MY_ENV=MY_VALUE" и проверить, установлены переменные окружения, или нет. Зарание скажу, что проверял на AIX, COMPAQ Tru64, SUN/SOLARIS.
И кстати, обрати внимание, что я ни словом не обмолвился о putenv() function, так как она действует именно так, как ты описал. |
Сообщ.
#9
,
|
|
|
2 alexsh:
Я не первый год в юниксе и уверен, что ты ошибаешься. Но все-таки, я проделал следующие действия : #env <длинный список переменных- skipped> #echo . export MY_VAR=MY_VALUE >> /etc/inittab #init q #env <почти тот же самый длинный список, в нем MY_VAR не фигурирует> #uname -a OSF1 ruaxp1.skipped.skipped.skipped V5.1 1885 alpha Что и требовалось доказать. Проделал я это (как ты видишь) на Compaq True64 V5.1A (Rev.1885). К такому же результату (вернее к его отсутствию) приводит это и на HP-UX 11.0 (uname -a: "HP-UX mguors B.11.00 U 9000/800 101901597 unlimited-user license"). Дома могу проверить с FreeBSD 4.6.2, но думаю смысла в этом нет. Если я проделал не то, что ты от меня хотел - объясни, что мне сделать, чтоб MY_VAR от init-а до шелла дошел по иерархии . Я же говорю - нет такого способа. У процессов память изолирована друг от дружки, пока явно не попросишь ее разделять (shared memory, etc....) с кем-то еще. |