Bash 如何使源命令在shell脚本之外生效?

Bash 如何使源命令在shell脚本之外生效?,bash,virtualenv,Bash,Virtualenv,我想编写一个小脚本来获取virtualenv(用于Python项目)目录的源代码。当我在我的项目目录中的某个地方时,我知道我的虚拟环境的“venv”目录位于我当前目录的祖先之一的目录中 我想写一个shell脚本,它将源代码venv/bin/activate,并且它的效果应该在这个shell脚本之外保持不变。这不是现在发生的事情 这是我的密码: #!/bin/bash #set -x while [ $PWD != "/" ]; do #echo $PWD if [ -d "v

我想编写一个小脚本来获取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的内容如下:
它是由工具生成的(通常与Python项目一起使用)。

您必须使用

source path/to/script

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


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

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


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

source
不起作用,
也不起作用。在这个shell脚本之外,效果似乎不会持久。可能这取决于venv/bin/activate的内容。你能在你的问题中加上这个吗?(或者,如果超过几行,请将其简化为一个演示问题的简短示例)当然,从包含
的脚本现在将在源文件中执行代码的意义上来说,这种方法“有效”。不起作用的是,在运行shell脚本的shell终止后,shell脚本的环境仍然无法持久化。@tripleee是的,同意。但是按照我理解问题的方式,似乎并不严格要求在shell终止后环境保持不变,因此我建议使用另一种方式来获得OP实际想要的效果。您的“source”命令有一个相对路径,这意味着它将尝试查找“venv”的脚本脚本从哪个目录执行。
. path/to/script