Получить системные переменные среды в C

Я написал приложение на C, которое должно считывать переменные окружения и соответствующим образом обрабатывать эти изменения. Когда приложение запускается, я настроил его, чтобы продолжить и инициализировать переменную (чтобы предотвратить возврат любых нулевых указателей) через setenv("MYVARIABLE", "TEST", 1).

Это приложение часто зацикливается, и во время этих циклов одной из его задач является проверка этой глобальной переменной через getenv("MYVARIABLE").

План состоял в том, чтобы изменить эти переменные окружения с помощью сценария оболочки или сценария Python. Приложение C работает в полноэкранном режиме, поэтому у меня нет возможности протестировать этот процесс без входа в другой терминал. В моем другом терминале (c2) я запускаю такие команды, как:

MYVARIABLE="My New Value"

or

export MYVARIABLE="My New Value"

Однако мое приложение, похоже, не улавливает обновление среды. Вместо этого он продолжает настаивать на том, что MYVARIABLE является «тестом», а не «моим новым значением». Я не уверен, почему эти две среды разделены, но мне нужно, чтобы они работали вместе. Кто-нибудь знает, что я делаю неправильно?

Моя система работает под управлением Archlinux для всех, кто заинтересован


person Freesnöw    schedule 20.06.2013    source источник
comment
Они разные, потому что вы запускаете два разных экземпляра оболочки.   -  person    schedule 20.06.2013
comment
H2CO3 Можно ли тогда установить переменную окружения для основной оболочки?   -  person Freesnöw    schedule 20.06.2013
comment
Я гуглю (вы тоже можете гуглить).   -  person    schedule 20.06.2013
comment
Если вы устанавливаете новые переменные в другом окне терминала, это в другом сеансе, почему бы не запустить вашу программу с помощью & (т.е. ./a.out &), чтобы вы могли ввести новые переменные в том же сеансе?   -  person Mike    schedule 20.06.2013
comment
Майк, Программа на самом деле является менеджером рабочего стола. Пользовательский интерфейс — это то, что занимает экран. Результат getenv("MYVARIABLE") должен отображаться на экране. Пока я не настрою поддержку терминала в диспетчере рабочего стола, я не смогу сделать что-то подобное.   -  person Freesnöw    schedule 20.06.2013


Ответы (2)


Проблема, с которой вы столкнулись прямо сейчас, заключается в том, что вы установили свою переменную только в области сеанса локальной оболочки. БЫВШИЙ:

(Предполагая bash) Когда вы устанавливаете переменную, например:

MYVARIABLE="My New Value"

это влияет только на текущую оболочку, когда вы устанавливаете ее как:

export MYVARIABLE="My New Value"

это влияет на текущую оболочку и все процессы, запущенные из текущей оболочки.

Если вы установите его в файле .bashrc, он будет установлен постоянно для всех будущих сеансов, но вам потребуется источник этого файла, чтобы он работал в текущем сеансе.


Лучшее решение — разветвить процесс. Например, если ваша программа называется a.out, вы можете выполнить:

> ./a.out &

Это позволит вам продолжать работать в сеансе оболочки во время работы программы, после чего вы сможете устанавливать переменные в том же сеансе.


Единственный другой вариант, который я когда-либо видел, - это заставить ваш сеанс оболочки "автоматически" исходить из вещей по мере их поступления:

1) В первом сеансе введите:

trap 'source ~/.bashrc' DEBUG

2) Затем запустите свою программу в том же сеансе:

./a.out

3) Во втором окне отредактируйте файл .bashrc, чтобы добавить новый env var

4) во втором окне источник новой версии файла:

source ~/.bashrc

Теперь первое окно, в котором запущена ваша программа, имеет новую переменную, установленную для его сеанса. Я использовал это раньше, и я знаю, что это работает, но я никогда не пробовал это в приложениях, которые уже были созданы ... но я подозреваю, что это должно работать для вас.

person Mike    schedule 20.06.2013

Ваша технологическая среда не может быть изменена динамически!!!

Помните этот прототип main()...

int main (int argc, char *argv[], char *envp[])
{
    char *path;

    /*
    Searches in this process envp[] only,
    There is no way it can access changes happening in Shell command prompt...
    User shell does not communicate with this process, if not piped.
    This will always return PATH, that was set at the time of starting.
    */
    while (1)
    {
        path = getenv("PATH");
        sleep (5);
        printf("PATH = %s\n", path);
        free(path);
    };
}

Ваше понимание библиотечной функции getenv() НЕВЕРНОЕ. Чтобы оправдать ваши ожидания, вам необходимо использовать любую форму IPC.

setenv() работает с собственной средой вызывающего процесса. Это будет передано его собственному дочернему процессу через системные вызовы fork(), exec(). Это ничего не сделает в родительском процессе, вашей оболочке.

person sukumarst    schedule 21.06.2013