【问题标题】:Set system variable from C++从 C++ 设置系统变量
【发布时间】:2011-11-23 14:04:14
【问题描述】:

这个shell脚本

#!/bin/csh
set VAR=12345
echo $VAR

将在 shell 中和平地给出输出 12345。 我需要在代码的某些部分使用 C++ 来做同样的事情:

string str = "12345";
retValue="set var1= "+str;      
system(retValue1.c_str());
system("echo $var1");

这不会创建系统变量 var1 并回显 null 这是可以理解的,因为每个系统函数都会创建具有不同环境变量的子进程。所以我只使用一个系统函数将它们组合如下......但它再次回显null。

retValue="set var1= "+str;
retValue1=retValue+";\n echo $var1";
system(retValue1.c_str());

有人可以指导我通过 C++ 设置系统变量吗? 提前非常感谢!

【问题讨论】:

  • 我认为他想在父shell中更改一个环境变量,这是不可能的......看我的回复

标签: c++ shell scripting


【解决方案1】:

setenv中的<cstdlib>

#include <cstdlib>

setenv("VAR", "12345", true);

【讨论】:

  • +1 用于使用正确的功能。其他几个答案推荐 putenv,但 putenv 不应使用。 setenv 是一个更好的接口。特别是 var 是自动变量的 putenv( var ) 经常会出现意想不到的行为。
  • @WilliamPursell 你能详细说明为什么不使用 putenv() 吗?只是好奇
  • 手册页说得最好:The string pointed to by string becomes part of the environment. A program should not alter or free the string, and should not use stack or other transient string variables as arguments to putenv(). The setenv() function is strongly preferred to putenv().
【解决方案2】:

你基本上做不到。

您可以调用putenv您自己的进程和所有未来的子进程中更改环境变量,但是没有没有办法 (这很好)改变 shell 进程的环境

您可以为您的 C++ 程序制定一个使用约定,例如它正在输出一些由用户获取(或eval-ed)的shell命令。 ssh-agent -s 就是一个例子。

【讨论】:

  • 原始发帖人的例子是system("set X=foo"),它不像他预期的那样工作......我对downvote 和其他答案感到惊讶。 Linux 程序无法强制更改父 shell(如果有)的环境。
  • 您是否 100% 确定发布者想要这样做?想要编写一个 C++ 程序来复制 set 从 shell 所做的事情会很奇怪。也许问题在于system("set X=Y") 启动了另一个进程,因此当它结束时更改会丢失。或许发帖人其实是想改变当前流程的环境。顺便说一句,我不是你的反对者。
  • 事实上,发帖人对我的回答的评论似乎证实了我的怀疑,但我确实认为这里有很大的混淆空间!!
【解决方案3】:

您可以使用putenv()

#include <cstdlib>
...
putenv("VAR=12345");

这样很方便,但是putenv不会复制字符串。这意味着如果您稍后对其进行修改,那么您将修改环境。这对于文字来说不是问题,但是使用std::string 形成字符串的方式与putenv() 并不兼容。

那么替代方法是使用setenv()

#include <cstdlib>
...
setenv("VAR", "12345", true);

使用setenv(),会制作输入副本,您可以在调用setenv() 后安全地处理字符串。

【讨论】:

  • 好,我很高兴听到。请记住接受其中一个答案。您选择哪一个。
  • +1:特别是,如果您调用 putenv( v ) 其中 v 是一个自动变量,然后从函数返回,则环境会被破坏。不要使用 putenv。始终使用 setenv。
【解决方案4】:

你想要的函数大概是putenv()。你没有指定你在哪个操作系统上,所以我假设是 Linux,因为那是我方便的手册页:

int putenv(char *string);

putenv() 函数增加或改变环境的值 变量。参数字符串的格式为 name=value。如果名字 环境中不存在,则将字符串添加到 环境。如果 name 确实存在,则 name 中的值 环境改变为价值。字符串指向的字符串 成为环境的一部分,因此更改字符串会更改 环境。

IIRC,win32 上也有一个 putenv。最后你可以试试看this question, possibly a dup

【讨论】:

  • setenv 应该优先于 putenv。
【解决方案5】:

以上答案正确解释了如何从基本上是setenv()的C++程序设置环境变量

我想说的唯一一点是为什么你的方法不起作用?原因是,当一个进程被加载时,system 命令被加载了新的上下文——相当于一个新的 shell。实际上你的环境变量 is 正在设置,但是当你回来时它会丢失。

请参阅此http://pubs.opengroup.org/onlinepubs/007904975/functions/setenv.html

事实上,setenv() 设置了 parent 进程的环境变量!这就是为什么它适合你。

【讨论】:

  • setenv()修改调用进程的环境
【解决方案6】:

请注意,在 &lt;cstdlib&gt; 标头中可用的功能中,其他方面非常出色的 CPPreference site 似乎没有提到 setenv,只有 getenv。这可能不是问题,因为我可以在带有 GCC 9.1 的 Centos 7 系统上使用 setenv by #include-ing &lt;cstdlib&gt;。我怀疑在大多数情况下&lt;cstdlib&gt; 只是&lt;stdlib.h&gt; 的一个薄包装。

另一个需要注意的小事是setenv 采用C 风格的字符参数(也用于设置环境变量的)。如果您使用 C++ 字符串(如您所愿),请不要忘记使用他们的 .c_str() 方法对其进行转换。

【讨论】:

    猜你喜欢
    • 2016-03-31
    • 2013-11-11
    • 2016-09-29
    • 2016-11-26
    • 2019-11-19
    • 2017-03-26
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    相关资源
    最近更新 更多