【问题标题】:chdir(getenv("HOME") prompts error "No such file or directory"chdir(getenv("HOME") 提示错误“没有这样的文件或目录”
【发布时间】:2015-11-02 19:06:17
【问题描述】:

对编写 shell 很陌生。当我不提供任何额外参数时,我试图让“cd”进入主目录。

但是当我调用“cd”并且代码尝试chdir(getenv("HOME"))时,它会显示一条错误消息"No such file or directory"

/*
  Builtin function implementations.
*/
int cd(char **args){
  if (args[1] == NULL){
    printf("%s\n", getenv("HOME"));
    if (chdir(getenv("HOME")) != 0) {
      perror("dsh");
    }
  } else if (chdir(args[1]) != 0){
    perror("dsh");
  }
  return 1;

}

getenv("HOME") 确实给出了正确的目录,即"/Users/oasisweng"

我想我做错了什么。我应该在哪里修?如果可能,请告诉我原因。

我已经阅读了 chdir man here,但是如果我手动输入 cd /Users/oasisweng,那么它将起作用。

谢谢!!

【问题讨论】:

  • 该代码没有问题。考虑发布MCVE
  • 你的代码在某处有chroot调用吗?
  • 你确定(args[1] == NULL)的结果是真的吗?尝试添加一些printf 调用,或在调试器下运行程序,这样您就可以确定它正在做您认为它正在做的事情。或者暂时将if 注释掉,以便它无条件地执行代码。 chdir(getenv("HOME")) 应该可以工作,但chdir(args[1]) 可能会也可能不会。 (我最好的猜测是args[1] 不是空指针,而是指向一个空字符串。)
  • BTW -- shell 标签用于 in shell 命令语言编写的代码。如果您有一个非常非常特定于实现 shell 的问题,也许这也是使用该标签的一个很好的理由——但这里不是这种情况;你也可以合理地让这个问题实现许多其他类型的程序。
  • 您是否尝试过使用stracesysdig 来查看调用的实际系统调用(因此,究竟传递了chdir() 的哪个参数)?您也可以使用 gdb 之类的调试器通过执行获得相同的信息跟踪。

标签: c posix chdir getenv


【解决方案1】:

感谢您的所有帮助,我在找出答案时尝试遵循 MCVE 指南。因为有人标记了我的问题,所以我觉得我应该分享我的答案。

我发现问题在于我最初设置$HOME的方式。

所以基本上,我的 shell 读取文件 profile 中的 $HOME$PATH 变量。它看起来像这样:

PATH=/bin:/usr/bin:/usr/local/bin\n
HOME=/Users/oasisweng\n

我用= 符号分割每一行,setenv 会将右侧的值保存到左侧的名称中。

问题是setenv 函数在调用时也会将\n 保存为$HOME 的一部分!

cd(getenv("HOME")) 实际上是cd("/Users/oasisweng\n"),最后有一个换行符。它失败了,因为它应该是cd("/Users/oasisweng")

我的解决方案是删除setenv之前右侧每个值的换行符:

int remove_newline(char* str){
  char* rst = strchr(str,'\n');
  if (rst != NULL){
    *rst = '\0';
    //found and changed
    return 0;
  } else{
    //not found
    return 1;
  }
}

轰隆隆!它已启动并运行。

这一课很琐碎,但我认为它仍然是一个有用的提醒。

【讨论】:

  • 嗯...那么,您是如何在profile 文件中得到这些额外的\n 的?你是如何设法让它们对getenv“可见”的?如果您在profile 中的行以正常的系统特定EOL 字符结尾,它将不会成为变量值的一部分,并且对getenv 不可见。看来您的解决方案实际上解决了真正问题的症状,而不是问题本身。
  • 所以在我的例子中,profile 是用崇高的文本编辑的。我为每个新行都按了 Enter 按钮。如何让我的输入按钮输入系统特定的 EOL 字符?
  • 我想我的意思是我没有输入shift+enter 的每一行,就像我没有输入.bash_profile 一样。有必要吗?
猜你喜欢
  • 2012-11-15
  • 2015-04-09
  • 2021-06-08
  • 2021-07-17
  • 1970-01-01
  • 2019-07-16
  • 1970-01-01
  • 2021-10-31
  • 1970-01-01
相关资源
最近更新 更多