gpt4 book ai didi

c - 简单linux shell中的环境变量

转载 作者:太空狗 更新时间:2023-10-29 11:39:27 24 4
gpt4 key购买 nike

我要用 C 为我的项目编写一个简单的 shell,它可以实现环境变量。我查阅了如何使用 getenv、setenv、putenv。到目前为止一切顺利,我已经尝试使用 getenv 来显示 shell 变量……好吧……取得了一些成功。但我觉得我的推理是有缺陷的。我有一个 char** argv,其中包含来自用户输入的解析输入。我现在检查 argv 是否以命令“echo”开头,然后检查以下任何输入是否以 $ 符号开头。这是我的代码:

int executeVariables(char** arguments){
int i = 0;
if(strcmp(arguments[i], "echo") == 0){
char *variable;
for(i = 1; arguments[i] != NULL; i++){
char *str = arguments[i];
if( *(str + 0) == '$'){
variable = getenv(str + 1);
}else{
variable = getenv(str);
}
if(!variable){
//puts("not a variable");
printf("%s ", arguments[i]);
}else{
//puts("a variable");
printf("%s ", variable);
}
}
printf("\n");
exit(0);
}

return 1;

}

我认为普通的 linux shell 会找到 $ 符号,它会在调用 echo 命令之前扩展变量。我的 shell 没有遵循这个原则,它在 echo 命令本身内部扩展变量。关于如何实现这个的任何想法?谢谢。

编辑:

我遇到的一个问题是:echo $HOMEecho HOME 给了我相同的错误结果。

编辑:

经过各种测试,一切正常。但要真正测试它,我需要创建一个局部变量,然后 echo 这个值。我尝试使用 putenv 函数,但它没有创建局部变量。

i = 0;
char** temp = malloc(sizeof (*temp));
if(strstr(userInput, "=") != NULL){
//puts("we got equals");
puts(userInput);
if(putenv(userInput) == 0){
printf("doing putenv(%s)\n", userInput);
exit(0);
}
else{
puts("couldnt putenv");
exit(1);
}
}

userInput:char *userInput 是使用 fgets() 从命令行获取的输入

最佳答案

您特别要求代码为字符串执行 getenv(),即使未找到 $。这就是它会查找 $HOME 或 HOME 的原因。只需删除找不到美元符号的 else 情况,并确保在声明时将变量初始化为 NULL,并将其放入循环中。

像这样:

// First, perform replacements
int executeVariables(char** arguments){
int i = 0;

for(i = 0; arguments[i] != NULL; i++){
char *str = arguments[i];

if(*str == '$'){
// make sure the result isn't NULL, though I'm not sure a real shell does
char *tmp = getenv(str + 1);
if (tmp != NULL) {
arguments[i] = getenv(str + 1); // save off the argument
}
}
}

// Then actually execute the function. This would be like bash's echo builtin
if (strcmp(arguments[0], "echo") == 0) {
int i;
for (i = 1; arguments[i] != NULL; i++) {
printf("%s ", arguments[i]);
}
printf("\n");
}

// Other functions could go here

return 1;
}

编辑:就您的方法而言,为什么要专门检查 echo ?为什么不让它通用,并检查所有参数,包括第一个参数?您实际上可能想要替换所有潜在的环境变量,因此如果您在某处设置了 MYECHO=echo,则以下内容将起作用。为了使它更通用,你需要这个函数,然后它会根据扩展变量执行这些东西。你可以把它做得很好,并有单独的功能,但为了适应这里的一切,我已经相应地更新了上面的代码,尽管我还没有测试它。 ;)

编辑:话虽这么说,werewindle 之前关于这样做的评论确实适用——替换参数,就像这里一样,然后使用更新后的参数数组让一个单独的函数做任何它需要做的事情做。 :)

> $MYVAR totally awesome $HOME
totally awesome /home/user

编辑:至于 putenv() 的情况,您需要如下所示的结构。这样,它将为 shell 以及您在 shell 中运行的任何其他进程设置它。

void do_args_env(char *args[])
{
// do putenv, etc.
}

// inside main loop in shell process
while (1) { // just an example
if (check_args_syntax(args) != 0) {
// error
}

do_args_env(args);

// fork and do other stuff
}

(希望是最终的)编辑:作为解释,进程通常不会(也许不能?)影响其层次结构中位于它们之上的进程的环境;只有相反。因此,如果您将 putenv() 放在一个 child 中,则该 child 的 sibling (即从其父进程派生的其他进程)将不会改变环境。

很高兴我能帮上忙!

关于c - 简单linux shell中的环境变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8328442/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com