问题说明:

问题说明:

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

ln -s /usr/bin/python python2 

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

python2: realpath couldn't resolve "/usr/bin/python2"

但像这样调用它./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"
    
    } 
    
  3. 将所有python2引用更改为python.自述文件建议这样做,但这实际上使版本控制变得毫无用处,因为系统将更改视为新版本,而实际上它不是(语义上)。

我一直在使用(3),但我正在尝试寻找更好的解决方案。我愿意接受这就是事情的本来面目(即,没有一种合适的方法来将“python2”指向/usr/bin/python可移植且不引人注目的,而不需要对测试套件和实际框架进行大量更改)。

答案1

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

#!/bin/bash
exec /usr/bin/python "$@"

使其可执行 ( chmod +x python2),然后您就可以开始工作了。

问题说明:

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

rm python2
ln /usr/bin/python python2

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

python2: posix_spawn: /Users/alexis/.../python22.7: No such file or directory

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

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

答案2

尝试:

ln -s /System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /usr/local/bin/python2

答案3

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

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

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

sudo ln -s /usr/bin/python /usr/local/bin/python2

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

答案4

您可以使用Unix命令readlink来查找链接的物理路径。

例子

假设我有以下链接:

$ ls -l /usr/bin/etags
lrwxrwxrwx. 1 root root 29 Dec 10 22:56 /usr/bin/etags -> /etc/alternatives/emacs.etags

$ ls -l /etc/alternatives/emacs.etags
lrwxrwxrwx. 1 root root 20 Dec 10 22:56 /etc/alternatives/emacs.etags -> /usr/bin/etags.ctags

$ ls -l /usr/bin/etags.ctags
lrwxrwxrwx. 1 root root 5 Dec 10 22:56 /usr/bin/etags.ctags -> ctags

  1. 查找符号链接指向的值

    $ readlink /usr/bin/etags
    /etc/alternatives/emacs.etags
    

    笔记:上面的结果可能是另一个链接。要解决此问题,请参阅下面的#2。

  2. 找出符号链接指向的值的绝对路径

    $ readlink -f /usr/bin/etags
    /usr/bin/ctags
    

相关内容