Добавление переменной окружения в Linux при помощи Golang до выхода пользователя из системы
Как можно добавить переменную окружения при помощи приложения на 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
Ответы (1 шт):
Если коротко, то никак.
Если развёрнуто, то окружение наследуется от родителя к потомку, но никак не в обратном направлении. То есть 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