Добавление переменной окружения в Linux при помощи Golang до выхода пользователя из системы

Рейтинг: 0Ответов: 1Опубликовано: 30.03.2023

Как можно добавить переменную окружения при помощи приложения на golang, чтобы она оставалась доступной после завершения работы приложения - до выхода пользователя из системы (аналогично команде export в Linux)?

os.Setenv - делает переменную только на время работы программы, а exec.Command - вообще не ставит переменную так, как мне необходимо.

Код:

func main() {
    //os.Setenv("LC_TEST", "TEST")
    cmd := exec.Command("export", "LC_TEST=TEST")
    _ = cmd.Run()
    myenv := os.Getenv("LC_TEST")
    fmt.Printf("My test env: %s \n", myenv)
    shellenv := os.Getenv("SHELL")
    fmt.Printf("SHELL = : %s \n", shellenv)
}

Вывод:

$ ./go_testenv
My test env:
SHELL = : /bin/bash
$ env | grep TEST
$ export LC_TEST2=TEST2
v$ env | grep TEST
LC_TEST2=TEST2

Ответы

▲ 0Принят

Если коротко, то никак.

Если развёрнуто, то окружение наследуется от родителя к потомку, но никак не в обратном направлении. То есть export в шелле создаёт переменную в окружении шелла, откуда её наследует запускаемый процесс. Если измените окружение в процессе, это могут увидеть его потомки, но никак не шелл, из которого запущен процесс.

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

export - это не программа, а встроенная инструкция шелла, которая обрабатывается особым образом.

DIRTY DIRTY HACK

Если вы чувствуете в себе силы на чёрный хакинг, то добавить переменную окружения в родительский шелл таки возможно. Нужно запустить отладчик gdb, приаттачиться к предку вы выполнить команду

(gdb) call (int)setenv("SOME_VAR", "some_val", 1)
(gdb) continue

затем прервать процесс и отсоединиться (detach) от предка.

Если при этом шелл навернётся и утянет за собой вашу программу... ну что ж, бывает.

Разумеется, нельзя так просто взять и поменять окружение предка. Мне потребовалось запускать sudo gdb, для обычного пользователя attach отвалился с ошибкой operation not permitted. Но переменная поменялась, есть такое.

 >$ set | grep ZZZ
 >$ echo $$
13863
 >$ sudo gdb 
GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
(gdb) attach 13863
Attaching to process 13863
0x00007ffbaacfc457 in __GI___waitpid (pid=-1, stat_loc=0x7ffd6b1040f0, options=10) 
(gdb) call (int)setenv("ZZZ", "xxx", 1)
$1 = 0
(gdb) continue
Continuing.
^C
Program received signal SIGINT, Interrupt.
0x00007ffbaacfc457 in __GI___waitpid (pid=-1, stat_loc=0x7ffd6b1040f0, options=10) 
(gdb) detach
Detaching from program: /bin/bash, process 13863
(gdb) quit
 >$ set | grep ZZZ
ZZZ=xxx