setenv和getenv文档

时间:2015-06-11 05:08:32

标签: c++ linux environment-variables system-calls

我知道这有点偏离主题,因为我们想知道这些例子是否做得好。

SETENV:

man page - setenv

包括: #include <stdlib.h>

声明: int setenv(const char *v_name, const char *v_value, int overwrite);

返回:如果成功返回零,否则返回-1,并设置errno以指示错误原因。

GETENV:

man page - getenv

包括: #include <stdlib.h>

声明: char *getenv(const char *name)

返回:如果成功返回指向环境中值的指针,或者如果没有匹配则返回NULL。

实施例

char *ppath在以下示例中用作变量。

示例1:此示例显示当overwrite参数为非零并且v_name具有值时会发生什么。

ppath = getenv("PWD");                  //puts the environment of $PWD into ppath
if(ppath == NULL)                       //error checking
  perror("getenv");   
cout << "$PWD = " << ppath << endl;     //prints the environment of $PWD 

此代码的输出为$PWD = /class/classes/username/CS100,这是因为char变量ppath正在获取 来自getenv("PWD")的环境和$PWD的环境为/class/classes/username/CS100。因此ppath指出了这一点 环境。还有正确的错误检查,以确保$PWD有一个环境,如果它没有perror 叫做。

ppath = getenv("HOME");                 //gets the environment of the $HOME
if(ppath == NULL)                       //error checking
  perror("getenv");
cout << "$HOME = " << ppath << endl;    //prints the environment of $PWD

此代码的输出为$HOME = /class/classes/username,这是因为char变量ppath正在获取 来自getenv("HOME")的环境和$HOME的环境为/class/classes/username。因此ppath指出了这一点 环境。还有正确的错误检查,以确保$HOME有一个环境,如果它没有perror 叫做。

if(-1==setenv("PWD",ppath,1))           //since the overwrite parameter is non-zero it replaces environment 
  perror("setenv");                     //of $PWD with the value of ppath which is defined by the environment 
                                        //of $HOME

这是为了更改$PWD的环境,在这种情况下,它采用ppath所指向的值,在这种情况下为/class/classes/username$HOME也是overwrite$PWD参数不为零,因此它将ppath的环境替换为ppath = getenv("PWD"); //gets the environment of $PWD if(ppath == NULL) //error checking perror("getenv"); cout << "$PWD = " << ppath << endl; //the value should now be the same as the value of $HOME

$PWD = /class/classes/username

此代码的输出为ppath,这是因为char变量getenv("PWD")正在获取 来自$PWD的环境和/class/classes/username的环境为ppath。因此$PWD指出了这一点 环境。还有正确的错误检查,以确保perror有一个环境,如果它没有$PWD = /class/classes/username/CS100 $HOME = /class/classes/username $PWD = /class/classes/username 叫做。示例1的完整输出如下。

输出1:

overwrite

示例2:此示例显示当v_name参数为非零时发生的情况,而v_name = ""的空值为ppath = getenv("PWD"); if(ppath == NULL) perror("getenv"); cout << "$PWD = " << ppath << endl; //in this case ppath ="" because the environment of $PWD is not set ,因此为空字符串。

$PWD =

以下代码的输出为$PWD,这是因为在这种情况下""的环境设置为ppath,它会使$PWD指向空串。因此它不会抛出错误的原因,但如果perror是未定义的变量,则调用ppath = getenv("HOME"); if(ppath == NULL) perror("getenv"); cout << "$HOME = " << ppath << endl;

$HOME = /class/classes/username

输出:此代码为ppath这是因为char变量getenv("HOME")正在获取 来自$HOME的环境和/class/classes/username的环境为ppath。因此$HOME指出了这一点 环境。还有正确的错误检查,以确保perror有一个环境,如果它没有if(-1==setenv("PWD",ppath,1)) //since the overwrite parameter is non-zero it replaces environment perror("setenv"); //of $PWD with the value of ppath which is defined by the environment //of $HOME 被称为。

overwrite

由于$PWD参数为1,因此ppath设置为ppath = getenv("PWD"); if(ppath == NULL) perror("getenv"); cout << "$PWD = " << ppath << endl; //the value should now be the same as the value of $HOME 的内容与前面示例中定义的无关。

$PWD = /class/classes/username

以下代码的输出为setenv,这是因为$PWD将过去代码块中定义的ppath的值更改为$PWD = $HOME = /class/classes/username $PWD = /class/classes/username

输出2:

overwrite

示例3:此示例显示当ppath = getenv("PWD"); if(ppath == NULL) perror("getenv"); cout << "$PWD = " << ppath << endl; 参数为零且v_name确实具有值时会发生什么。

ppath

在这种情况下,$PWD设置为$PWD = /class/classes/username/CS100的环境。此代码块的输出是 ppath = getenv("HOME"); if(ppath == NULL) perror("getenv"); cout << "$HOME = " << ppath << endl;

ppath

在此代码块中,$HOME设置为$HOME = /class/classes/username的环境。以下代码块的输出将是 if(-1==setenv("PWD",ppath,0)) //since the overwrite parameter is zero it does not replaces perror("setenv"); //environment of $PWD with ppath.

overwrite

这里有一个ppath参数为零的新案例。在这种情况下,$PWD是什么并不重要,因为 零标志使ppath不被$PWD替换,除非$PWD是未定义的变量,在这种情况下 ppath的值为ppath = getenv("PWD"); if(ppath == NULL) perror("getenv"); cout << "$PWD = " << ppath << endl; //the value should not be changed.

$PWD = /class/classes/username/CS100

此代码块的输出为setenv。这是因为$PWD没有改变 因overwrite参数而导致$PWD = /class/classes/username/CS100 $HOME = /class/classes/username $PWD = /class/classes/username/CS100 的环境。

输出3:

overwrite

示例4:此示例显示当v_name参数为零为非零时发生的情况,ppath = getenv("HOME"); if(ppath == NULL) perror("getenv"); cout << "$HOME = " << ppath << endl; 是未在环境中定义的参数

$HOME

在这种情况下,ppath被赋予$HOME = /class/classes/username的环境,还有正确的错误检查。代码的输出 阻止是if(-1==setenv("random_name",ppath,0)) //since the overwrite parameter is zero and the variable perror("setenv"); //$random_name is undefined, setenv makes the environment of //$random_variable is the value of ppath. If the case where //there is a undefined variable the setenv behaves the //same way regardless of a non-zero or zero overwrites parameter.

overwrite

在这种情况下,v_name参数仍为零,但未声明overwrite,因此random_name参数为零是有用的。在这种情况下,ppath设置为$HOME,该/class/classes/username指向ppath = getenv("random_name"); //gets the value of $PWD if(ppath == NULL) perror("getenv"); cout << "$random_name = " << ppath << endl; //the value should now be the same as the value of $HOME ppath的环境。

$random_name

setenv包含$random_name = /class/classes/username的环境,该环境由前一个代码块中的$HOME = /class/classes/username $random_name = /class/classes/username 设置。输出 此代码块的行为是{{1}}

输出4:

{{1}}

1 个答案:

答案 0 :(得分:-1)

您正在使用C ++;您可以在编写时轻松声明变量。实际上,C99和C11都允许您在使用变量时声明变量。

示例1

  

示例1:此示例显示当overwrite参数为非零且v_name具有值时会发生什么。

实际上,很难发现示例1中与overwrite参数有关的代码。

ppath = getenv("PWD");                  //puts the environment of $PWD into ppath
if(ppath == NULL)                       //error checking
  perror("getenv");   
cout << "$PWD = " << ppath << endl;     //prints the environment of $PWD

当您确定它为NULL时,不应使用ppath;这是一个普遍存在的问题。这些天,你不应该使用nullptr因为这是C ++吗?我想这可能是:

const char *ppath = getenv("PWD");
if (ppath == nullptr)
    perror("getenv");   
else
    cout << "$PWD = " << ppath << endl;

如果您声明您正在编写向后兼容性代码,那么使用NULL或0代替nullptr没有任何重大问题。

实际上,你有三次相同的代码块;你需要写一个函数:

void show_env(const char *varname)
{
    const char *ppath = getenv(varname);
    if (ppath == nullptr)
        perror("getenv");   
    else
        cout << "$" << varname << " = " << ppath << endl;
}

这是原始代码的直接音译。它还说明了为什么perror()是一个不好的函数;很难使错误消息有意义(它不包括变量名称)。除此之外,getenv()的POSIX规范未指定由errno设置getenv(),我们应该将代码修改为:

void show_env(const char *varname)
{
    const char *ppath = getenv(varname);
    if (ppath == nullptr)
        cerr << "No value in the environment for $" << varname << endl;   
    else
        cout << "$" << varname << " = " << ppath << endl;
}

然后你可以打电话:

show_env("PWD");
show_env("HOME");
…code using setenv()…
show_env("PWD");

等。我不相信引用$HOME的代码是相关的;你真的不使用它。

就个人而言,我不喜欢(强烈地)你在setenv()的代码中使用的从后到前的比较风格。当尤达我想说话时......

请注意,单独设置环境变量$PWD不会更改当前工作目录。

示例2

您的示例2没有清楚地显示v_name设置为空字符串。但是,这是setenv()的POSIX规范所涵盖的情况。这次,定义了错误(errno将设置为EINVAL)。

有很多重复的代码,再一次,很难发现什么是有趣的。

示例3

你说:

  

示例3:此示例显示当overwrite参数为零且v_name确实具有值时会发生什么。

我认为你的意思是:

  

示例3:此示例显示当overwrite参数为零且由v_name标识的环境变量确实具有值时会发生什么。

这也可能以前适用。

示例4

你说:

ppath = getenv("random_name");                  //gets the value of $PWD

评论与代码不符。

SO上的风格

您应该为每个示例创建一个标题,并以###作为行前缀。您可能有也可能没有超标题## Examples。您可以模仿函数大纲的手册页的样式,或者您可以简单地省略除概要之外的所有内容,指定函数行为的定义位置。

正如所写的那样,很难找到4个例子(在回答的过程中,我才意识到四个例子而不是三个例子)。你有很多重复。你也有很多噪音(引用$HOME的代码基本上是噪音。