【MSYS2】隐式路径风格转换

参考文档:https://www.msys2.org/docs/filesystem-paths/

路径风格

Windows系统和Unix系统有两套截然不同的文件路径风格,我们平时遇到的路径形式大致如下:

    1. C:\nope该字符串是一个合法的Windows绝对路径,代表C盘下的nope文件或目录。
      该字符串不是合法的Unix路径。
    1. C:/nope该字符串是一个合法的Windows绝对路径,代表C盘下的nope文件或目录。
      该字符串不是合法的Unix路径。
    1. /foo该字符串是一个合法的Windows相对路径,代表当前盘符下的foo文件或目录(如果程序的当前工作目录在C盘,则其表示的绝对路径为C:\foo)。
      同时,该字符串也是一个合法的Unix绝对路径,代表根目录/下的foo文件或目录。
      在日常编程中,绝大多数情况下/foo都指代Unix绝对路径,因此我们把这种路径风格称为Unix路径风格,或称为貌似Unix的路径风格
    1. foo/bar该字符串是一个合法的Windows相对路径,也是一个合法的Unix相对路径,都代表程序当前工作目录下的foo/目录下的bar文件或目录。

转换规则

Cygwin工具

如果你的可执行文件被安装到/usr/bin这个位置,或者在安装包时不需要指定包前缀,则该包属于MSYS环境。通过这些包安装的程序被称为Cygwin工具

举例

  • /usr/bin/ls, /usr/bin/cat, /usr/bin/bash这些可执行文件都属于Cygwin工具
  • 通过pacman安装的没有包前缀的包也属于Cygwin工具。如通过如下命令pacman -S vim, pacman -S git安装的/usr/bin/vim/usr/bin/git

Cygwin工具只保证正确解析Unix风格的路径,是否可以正确解析Windows风格的路径,取决于该Cygwin工具的内部实现。

MSYS2不会自动将Windows风格的路径转换为Unix风格

如果你提供了Windows风格的路径给某个Cygwin工具,MSYS2并不会自动将Windows风格的路径转换为Unix风格,能否正确解析该路径字符串,完全依赖于该Cygwin工具的内部实现。

举例

  • ls命令对应着Cygwin工具/usr/bin/ls。在执行ls C:/Users命令时,MSYS2并不会自动将Windows风格的路径C:/Users转换为Unix风格的路径/c/Users。之所以该命令能够正确执行,是因为Cygwin工具/usr/bin/ls在底层实现中调用了Windows系统的API,并且/usr/bin/ls原封不动地将输入参数C:/Users传递给了底层Windows接口。

Windows原生工具

如果你的可执行文件被安装到类似/ucrt64/bin, /mingw64/bin这些位置,或者在安装包时指定了包前缀,则该包属于其它环境(如UCRT64环境、MINGW64环境等)。通过这些包安装的程序被称为Windows原生工具
此外,如果在MSYS2中直接执行Windows系统上原生安装的程序,这些“Windows系统上原生安装的程序“也算作Windows原生工具

举例

  • 通过pacman安装的指定了包前缀的包属于Windows原生工具。如通过如下命令pacman -S mingw-w64-ucrt-x86_64-python, pacman -S mingw-w64-x86_64-perl安装的/ucrt64/bin/python3/mingw64/bin/perl
  • 在MSYS2中使用Windows上原生安装的应用程序,这些程序也算作Windows原生工具。比如我在Windows系统上从Python官网安装了python解释器,然后在MSYS2中使用了它,那么这个python解释器也属于Windows原生工具

Windows原生工具只保证正确解析Windows风格的路径,这些程序和你在Windows上直接安装的其它原生程序没有本质区别。

举例

  • 假设我们的MSYS2安装在C:/msys64/目录下。
  • 让Windows原生工具/ucrt64/bin/python3执行以下脚本文件path_test.py,脚本的含义是“打印/Users/目录的绝对路径”。
# path_test.py
import os
print(os.path.abspath('/Users/'))

我们已经知道,/Users/这种路径风格在Windows和Unix下都是合法的,但代表的含义不同。那么Windows原生工具/ucrt64/bin/python3会将这个路径理解为哪种风格呢?
观察解释器的输出:

/ucrt64/bin/python3 path_test.py
# 返回 C:/Users

结果很明了,Windows原生工具/ucrt64/bin/python3将路径/Users/理解为一个Windows风格的相对路径
在MSYS2中使用这类Windows原生工具的时候,请特别小心这种情况!因为Windows原生工具只保证正确解析Windows风格的路径,如果你在脚本文件中试图使用Unix风格的绝对路径(如/tmp/等),这些路径将会被Windows原生工具理解为Windows风格的相对路径/tmp/被理解为工作盘符:/tmp/),这完全不是你想要的结果!

在特定情况下,MSYS2会自动将“貌似Unix风格的路径”转换为Windows风格

尽管Windows原生工具只保证正确解析Windows风格的路径,MSYS2为我们提供了两种“隐式路径风格转换”的情况——如果你通过以下两种方式之一

    1. Bash命令行传参
    1. Bash环境变量

提供了貌似Unix风格的路径给某个Windows原生工具,MSYS2会自动将貌似Unix风格的路径转换为Windows风格。最终,这个Windows原生工具会接收到一个“被MSYS2隐式转换后”的Windows风格路径。

举例

  • 假设我们的MSYS2安装在C:/msys64/目录下。
  • 通过Bash命令行给Windows原生工具/ucrt64/bin/python3提供一个“貌似Unix风格的”绝对路径参数--dir=/foo。通过返回的结果可以发现,Python接受的第二个输入参数被MSYS2自动转换为了--dir=C:/msys64/foo
    MSYS2自动将/foo路径中的”根目录/“替换为了MSYS2的安装目录C:/msys64/
/ucrt64/bin/python3 -c "import sys; print(sys.argv)" --dir=/foo
# 返回 ['-c', '--dir=C:/msys64/foo']
  • 通过Bash环境变量给Windows原生工具/ucrt64/bin/python3提供包含“貌似Unix路径”的环境变量MYVAR=/foo。通过返回的结果可以发现,Python在读取环境变量MYVAR值的时候,值被MSYS2自动转换为了C:/msys64/foo
MYVAR=/foo /ucrt64/bin/python3 -c "import os; print(os.environ['MYVAR'])"
# 返回 C:/msys64/foo

再次强调,MSYS2的隐式路径转换只有在以下两种情况时有效

    1. Bash命令行传参
    1. Bash环境变量

如果你在Python脚本文件里写了/foo路径,然后让Windows原生的Python解释器去执行这个脚本,那么解释器会直接将它理解为Windows风格的相对路径盘符:/foo,而不是MSYS2隐式转换过的MSYS2安装目录/foo

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值