如何让“realpath”找到我的符号链接?

Ave*_*han 12 python symlink

我在 MacOSX 上bash用作我的外壳。我有符号链接,创建如下:

ln -s /usr/bin/python python2 
Run Code Online (Sandbox Code Playgroud)

我有一个使用 python2 的包,我想在我当前的工作目录中创建一个/usr/bin/python实际上是 python2的符号链接。当我python2从命令行执行 a 时,我收到此错误:

python2: realpath couldn't resolve "/usr/bin/python2"
Run Code Online (Sandbox Code Playgroud)

但是像这样调用它./python2可以正确解析路径。我PATH已经.在里面。事实上,为了测试,我修改了它,使其只包含.在其中。

我该如何解决?谢谢!


语境

以下许多建议的解决方案对我不起作用。我试图将我的问题提炼得尽可能集中和简短,这样人们就不会淹没在文字的海洋中,但显然我需要提供更多的背景知识。

我正在尝试对从 git 克隆的包进行开发。原始软件包git-multimail是/是在 Linux 的某个变体上开发的(我猜是 Ubuntu)。我一直在尝试修改它,以便能够在 MacOSX 上使用它及其测试套件,并且尽可能少地修改。这就是为什么一些建议的解决方案不理想的原因:

  1. 以 rootpython2身份在 /usr/bin/ 中创建一个符号链接。我正在寻找不需要这个的解决方案。这在开始时是一个明显的选择,但我想要一个尽可能少修改主机系统的解决方案。这就是为什么我想在当前工作目录中创建一个临时符号链接,将 CWD(即.)添加到我的路径中,然后在完成后销毁它(即符号链接)。

  2. 创建一个包装脚本以使用现有的 python 调用 python 脚本。这样做的问题是,大部分测试套件使用实际的 script_files 作为可执行文件,这取决于 shebang 来找到正确的执行环境。这意味着要大量编辑测试套件。在这种情况下,(请参阅下面的测试框架片段),我必须为每个.py文件添加一个包装器;此外,用户/开发人员必须了解使用包的不同规则,具体取决于它们所在的系统(即在 MacOSX 上,请确保不要使用 python 文件而不通过包装器调用它们或显式调用/usr/bin/python file.py)。

    #! /bin/sh
    
    D=$(cd $(dirname "$0") && pwd)
    MULTIMAIL="$D/../git-multimail/git_multimail.py"
    POST_RECEIVE="$D/../git-multimail/post-receive"
    
    TESTREPO=$("$D/create-test-repo")
    
    HOME="$D"
    XDG_CONFIG_HOME="$D"
    GIT_CONFIG_NOSYSTEM=1
    export HOME XDG_CONFIG_HOME GIT_CONFIG_NOSYSTEM
    
    cd $TESTREPO
    
    test_email() {
        REFNAME="$1"
        OLDREV="$2"
        NEWREV="$3"
        echo "$OLDREV" "$NEWREV" "$REFNAME" | USER=pushuser "$MULTIMAIL"
    
    } 
    
    Run Code Online (Sandbox Code Playgroud)
  3. 将所有python2引用更改为python. 自述文件建议了这一点,但这实际上使版本控制变得无用,因为系统将更改视为新版本,而实际上它不是(语义上)。

我一直在使用 (3),但我正在努力寻找更好的解决方案。我愿意接受事情就是这样(即没有合适的方式将“python2”指向/usr/bin/python可移植且不显眼的,而不会对测试套件和实际框架进行大量更改)。

ale*_*xis 17

我相信您与 Apple 用于管理和切换同一程序的多个版本的系统发生冲突。你可以完成你想要的,不太优雅但没有问题,使用以下名为 的脚本python2

#!/bin/bash
exec /usr/bin/python "$@"
Run Code Online (Sandbox Code Playgroud)

使其可执行 ( chmod +x python2),然后您就可以开展业务了。

问题说明:

运行时/usr/bin/python,它会python2.7 在同一目录中查找并执行您的符号链接失败,因为系统遵循符号链接到/usr/bin,然后查找并未能找到 python2。您可以通过使用“硬链接”而不是符号链接来更进一步:

rm python2
ln /usr/bin/python python2
Run Code Online (Sandbox Code Playgroud)

现在没有要遵循的符号链接,只有同一个文件(inode)的两个文件名。但现在我失败并显示以下消息:

python2: posix_spawn: /Users/alexis/.../python22.7: No such file or directory
Run Code Online (Sandbox Code Playgroud)

请注意python22.7:框架正在添加2.7到您创建的名称中!与其试图解开这个问题并建立一个符合其预期的链接森林,我建议您远离版本管理框架,并使用上面建议的解决方案。

附注。可能有更好的解决方案:如果您要解释开始时需要做什么(为什么需要提供python2的别名python),那么有人可能会以不同的方式帮助您完成。这在 stackexchange 术语中被称为“XY 问题”...


小智 5

尝试:

ln -s /System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /usr/local/bin/python2
Run Code Online (Sandbox Code Playgroud)


Asy*_*abs 2

如果您需要解析(或调查)符号链接,您可以使用独立于平台的 bash 库“realpath-lib”。默认情况下,它模拟 readlink 并且可以在 Mac 或 Unix 上运行。它可以在GithubBitbucket上找到,而且是免费的。

但听起来你只想从本地(工作)目录执行 python2 (而不是 ./python2)。可以使用 .bashrc 中的别名来完成此操作,否则您需要将工作目录(包含符号链接)添加到 PATH 环境变量中。也可以仅对当前会话执行此操作,或者在未来会话的 .bashrc 文件中执行此操作。这可能是仅针对特定用户的解决方案。

另一个适用于所有用户的选项是在路径上的另一个目录(例如 /usr/local/bin)中创建指向 /usr/bin/python 的 python2 符号链接。也许是这样的:

sudo ln -s /usr/bin/python /usr/local/bin/python2
Run Code Online (Sandbox Code Playgroud)

然后任何用户或脚本都应该找到 python 或 python2 命令。当然,此选项需要管理员(root)权限才能安装。