【问题标题】:What can I do if getcwd() and getenv("PWD") don't match?如果 getcwd() 和 getenv("PWD") 不匹配怎么办?
【发布时间】:2010-07-17 00:43:08
【问题描述】:

我有一个构建系统工具,它使用getcwd() 来获取当前工作目录。这很好,只是有时人们的路径中有空格,而构建系统不支持这一点。你会认为你可以只做一个符号链接:

ln -s "Directory With Spaces" DirectoryWithoutSpaces

然后快乐。但不幸的是,getcwd() 解析了所有的符号链接。我尝试使用getenv("PWD"),但它指向的路径与我从getcwd() 返回的路径不同。我认为我责怪make -C 没有更新环境变量。现在,getcwd() 给了我一条这样的路径:

/Users/carl/Directory With Spaces/Some/Other/Directories

getenv("PWD") 给了我:

/Users/carl/DirectoryWithoutSpaces

那么 - 有没有像 getcwd() 这样的函数不能解析符号链接?

编辑:

我变了

make -C Some/Other/Directories

cd Some/Other/Directories ; make

然后getenv("PWD") 起作用了。如果没有其他解决方案,我可以使用它。

【问题讨论】:

  • 程序的哪一部分因为路径中的空格而无法运行?
  • mv ~/"Directory With Spaces" ~/DirectoryWithoutSpaces? :P
  • @eruciform,有问题的工具会生成一堆makefile;如果这个路径名中有空格,由于很多原因,它会窒息。我已经进行了编辑中提到的更改,现在我正在整体修复空格问题,但不管怎样,生成带有混合符号链接和解析路径名的 makefile 有点奇怪。我上面的编辑解决了这个问题,但我仍然对替代解决方案感兴趣。
  • @eruciform,经过进一步调查,修复所有这些垃圾以使用空格是永远不会发生的。正确的解决方案是删除绝对路径要求,而不是试图让空间发挥作用。

标签: c macos makefile getcwd getenv


【解决方案1】:

根据 Stevens 的《UNIX 环境高级编程圣经》第 112 页:

由于内核必须保持当前工作目录的知识,我们应该能够获取它的当前值。不幸的是,内核为每个进程维护的只是当前工作目录的 i 节点编号和设备标识。内核不维护目录的完整路径名。

抱歉,看来您确实需要以其他方式解决此问题。

【讨论】:

  • 是的,对不起。希望答案有所帮助。
  • 似乎任何答案都可能如此。我编辑中的解决方法对我来说没问题。谢谢!
【解决方案2】:

getcwd() 无法确定您通过符号链接所遵循的路径。 getcwd()的基本实现先统计当前目录'.',然后打开父目录'..'并扫描条目,直到找到与'.'相同inode号的目录名有.然后它向上重复该过程,直到找到根目录,此时它具有完整路径。它绝不会遍历符号链接。因此,让getcwd() 计算符号链接所遵循的路径的目标是不可能的,无论是作为系统调用还是作为库函数实现。

最好的解决办法是确保构建系统处理包含空格的路径名。这意味着引用通过 shell 的路径名。 C 程序不关心名称中的空格;只有当像 shell 这样的程序解释你遇到问题的字符串时。 (作为运行预处理器的 shell 脚本实现的编译器通常会遇到包含空格的路径名问题 - 根据经验。)

【讨论】:

  • 是的 - 显然 getcwd() 不起作用。我希望找到一个替代方案——我的编辑显示了一个。让构建系统处理空间是一场彻头彻尾的噩梦——GNU make 在处理它们方面是出了名的糟糕。我认为消除绝对路径要求会更容易,但仍然没有野餐。
猜你喜欢
  • 2016-08-07
  • 2019-07-06
  • 2014-09-10
  • 1970-01-01
  • 1970-01-01
  • 2014-09-28
  • 2014-08-09
  • 1970-01-01
相关资源
最近更新 更多