【问题标题】:How do I get a source command to take effect outside the shell script?如何让源命令在 shell 脚本之外生效?
【发布时间】:2012-12-03 07:36:09
【问题描述】:

我想编写一个小脚本来获取我的 virtualenv(用于 Python 项目)目录。当我在我的项目目录中的某个地方时,我知道我的虚拟环境的“venv”目录位于我当前目录的祖先之一的目录中。

我想编写一个 shell 脚本,该脚本将提供 venv/bin/activate,并且它的效果应该在这个 shell 脚本之外持续存在。这不是现在发生的。

这是我的代码:

#!/bin/bash

#set -x

while [ $PWD != "/" ]; do
    #echo $PWD
    if [ -d "venv" ]; then
        echo "venv found in $PWD. Sourcing."
        source venv/bin/activate
        break
    else
        cd ..
    fi
done

为什么它现在不起作用,我该如何解决?

编辑:

如果有帮助,venv/bin/activate 的内容在这里:http://pastebin.com/TZ40brsq 它由virtualenv 工具生成(一般用于Python 项目)。

【问题讨论】:

  • 你的“source”命令有一个相对路径,这意味着它会尝试从执行脚本的目录中找到“venv”目录。

标签: bash virtualenv


【解决方案1】:

您将不得不使用调用脚本

source path/to/script

. path/to/script

(同样的事情)而不是运行它。这是一种安全措施,当您运行程序时,它不能更改其父进程的环境(即您的 shell 会话)。但是,当您使用 source 时,您是在告诉 shell 读取文件的内容并像您自己键入内容一样运行它。

如果您已经以这种方式获取脚本,那么我不确定发生了什么。

【讨论】:

  • source 无效,. 也无效。该效果似乎不会在此 shell 脚本之外持续存在。
  • 可能取决于venv/bin/activate的内容。您可以将其添加到您的问题中吗? (或者如果超过几行,则将其简化为演示问题的简短示例)
  • 当然,这“有效”是因为包含. 的脚本现在将执行源文件中的代码。不起作用的是,在运行它的 shell 终止后,shell 脚本的环境仍然不存在。
  • @tripleee 是的,同意。但是我阅读问题的方式似乎并不严格要求环境在 shell 终止后持续存在,所以我建议一种不同的方法来获得 OP 实际想要的效果。
【解决方案2】:

您不能通过使用在子进程中运行的 shell 脚本来影响当前环境。

如果在 while 循环之前添加 pushd "$(pwd)" 并在之后添加 popd,则可以通过获取脚本文件而不是执行它来获得所需的内容

【讨论】:

    猜你喜欢
    • 2014-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 2014-12-13
    • 2017-06-02
    • 2021-11-21
    • 2016-10-01
    相关资源
    最近更新 更多