0%
sudo使用#02#sudo执行程序找不到环境变量的问题

有时我们明明已经设置了环境变量,但使用sudo执行程序,程序却无法正常获得环境变量的值。究其原因,使用sudo,系统会重置环境变量,亦即,先前设置的变量都会失效,只有少数配置文件中指定的环境变量能够保存下来。

接下来,我们先演示下这种情况的现象,然后再说解决方法。

测试

首先我们编写一个 测试程序用例,如下面的文件所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdlib.h>
#include <stdio.h>

// gcc -o envtest envtest.c

int main()
{
char* e_env_a = getenv("ENV_TEST_A");

char* e_env_b = getenv("ENV_TEST_B");

printf("ENV_TEST_A : %s\n", (e_env_a?e_env_a:"null"));

printf("ENV_TEST_B : %s\n", (e_env_b?e_env_b:"null"));

return 0;
}

我们在服务器上编译测试代码文件,执行之前先给 ENV_TEST_B 赋值,然后我们分别不使用sudo和使用sudo来执行程序,观察下 ENV_TEST_B 值是否可以正确获取。

执行过程如下图所示:

我们使用sudo之后,ENV_TEST_B获取不到了。

其根本原因是,sudo配置文件 /etc/sudoers 中配置项 Defaults env_reset 指定使用sudo,就重置环境变量。

我们可以使用下面三种方法来保留环境变量。

通过设置 env_reset 来保留环境变量

我们既然知道是 Defaults env_reset 所限制,如果当前是测试环境并且对安全性要求不高,我们完全可以简单粗暴的将该配置项禁止即可。
方法就是将其改为 Defaults !env_reset

文件修改后如下图所示:

通过使用 sudo -E 来保留环境变量

-E, –preserve-env
Indicates to the security policy that the user wishes to preserve their existing environment variables.
The security policy may return an error if the user does not have permission to preserve the environment.

我们可以使用 sudo 的 “-E” 选项来执行程序,加上该选项后,sudo执行时会保留当前用户已存在的环境变量,而不被重置。

我们清理下当前环境变量,重复上述的测试步骤,再看下 sudo -E 的执行过程:

通过设置 env_keep 来保留环境变量

我们在 /etc/sudoers 文件中发现有些 env_keep 配置项,它们的作用是用于保留部分环境变量不被重置,需要保留的变量就写入双引号之中。所以我们可以通过在配置文件中,显示指定我们要保留的配置项。因为 /etc/sudoers 会包含 /etc/sudoers.d 目录下的配置文件,为了增加和后续修改的方便,我们在 /etc/sudoers.d 目录增加一个独立的配置文件,用于配置 env_keep。

在 /etc/sudoers.d 中新建文件 env_keep ,其内容如下:

1
Defaults env_keep += "ENV_TEST_B"

修改后的文件如下图所示:

我们清理下当前环境变量,然后重复上述的测试步骤,再看下 sudo 的执行过程:

参考资料