我要为我的项目编程一个简单的外壳,可以实现环境变量。我查看了如何使用getenv,setenv,putenv。到目前为止,我尝试使用getEnv显示壳变量...好吧...有些成功。但是我觉得我的推理有缺陷。我有一个 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外壳找到了 $ 符号,它在调用echo命令之前会扩展变量。我的外壳不遵循此原则,它是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);
    }
}

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

有帮助吗?

解决方案

您特别要求为字符串执行getEnv()代码,即使找不到$。这就是为什么它会查找$ home或home的原因。只需删除其他情况即可找到美元标志,并确保在声明时将变量初始化为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,则以下将有效。为了使其更通用,您将拥有此功能,然后将根据扩展的变量执行这些功能。您可以使所有功能都很好并具有单独的功能,但是为了将所有功能都放在这里,尽管我没有对其进行测试,但我已经相应地更新了上面的代码。 )

编辑: 话虽这么说,Wayswindle对此事的评论确实适用 - 替换参数,例如这里,然后使用更新的参数数组来具有单独的函数,请执行任何操作。 :)

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

编辑: 至于putenv()情况,您将需要以下构造的内容。这样,它将设置为外壳以及您在外壳中运行的任何其他过程。

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
}

(希望最终)编辑: 作为一种解释,过程通常不会(也许不能?)影响其层次结构上方的过程环境;只是相反。因此,如果您将孩子放在孩子中,那么孩子的兄弟姐妹(即与父母分配的其他过程)不会改变环境。

很高兴我能提供帮助!

其他提示

是的,普通外壳在解析命令行期间扩展变量。因此,您需要在功能中替换变量,该变量会产生“包含从用户输入中解析的输入”的数组。在这种情况下代码 echo (和其他命令)将要短得多。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top