我正在从启动脚本启动 URxvt 终端。当终端启动时,我想在加载特定 Python 虚拟环境的特定目录中工作。这些是在已运行的终端中完成此操作的命令:
$ cd myproject
$ workon myvirtualenv
那么启动这个终端需要什么命令呢?我尝试了以下方法:
# called from startup script:
/usr/bin/urxvt -e bash -ic 'cd myproject; workon myvirtualenv'
这有效,但很难察觉,因为终端在两个命令完成后立即退出,这几乎是立即的。我可以通过调用来防止这种情况发生bash
再次,像这样:
# called from startup script:
/usr/bin/urxvt -e bash -ic 'cd myproject; workon myvirtualenv; exec bash -i'
但是现在虚拟环境在 bash 的第二个实例中不再激活,尽管命令的效果cd
确实仍然存在。
如何使用激活的虚拟环境生成 URxvt 终端?
答案1
workon
是一个函数(而不是一个单独的可执行文件),其原因如下:它的作用是在当前 shell 中设置某些内容。我不使用该工具,也不知道详细信息。它是否设置变量、函数、别名、陷阱、shell 选项或其他内容无关紧要。重要的是,当您运行 时exec bash -i
,会启动一个新bash
程序,并且至少其中一些自定义设置不会保留。
解决方案:使其精确地bash -i
运行workon myvirtualenv
。
这个想法是在一个环境中运行,exec bash -i
在这个环境中,某些环境变量的存在和内容将告诉 shell 运行workon …
。将其添加到您的~/.bashrc
:
[ -n "$AUTOWORKON" ] && workon "$AUTOWORKON"
必须执行后 workon
已定义。你的尽头~/.bashrc
很可能是最好的地方。
以这种方式运行urxvt
:
/usr/bin/urxvt -e sh -c 'cd myproject; AUTOWORKON=myvirtualenv exec bash -i'
笔记:
第一个 shell 不需要是
bash
;它不需要是交互式的。我用的是sh -c …
,应该没问题。AUTOWORKON
将在 的环境中bash
,因此如果您再运行另一个bash
读取~/.bashrc
,那么它也workon …
将从文件中的行执行。我不知道您是否想要这个。如果不是,请unset AUTOWORKON
在~/.bashrc
使用它的值后。将我们的行更改为:[ -n "$AUTOWORKON" ] && { workon "$AUTOWORKON"; unset AUTOWORKON; }
另一种可能性是从变量中删除导出属性:
export -n AUTOWORKON
。我随意选择了
AUTOWORKON
变量的名称。如果它与您当前设置中的任何内容相冲突,则使用其他名称。
答案2
我找到了另一个选择。非常感谢卡米尔让我走上正确的道路!以下命令将生成一个不会立即退出的新终端:
urxvt -e bash --rcfile <(echo '. /etc/bash.bashrc; . ~/.bashrc; cd myproject; workon myvirtualenv')
解释:
urxvt
:启动 URxvt。-e bash --rcfile ...
:启动时,bash
使用--rcfile
参数执行。这将获取后面的文件名代替默认.bashrc
文件。<(echo ...)
: 特殊 bash 语法流程替代。这会将括号内的命令替换为文件名,例如,/dev/fd/62
其中包含命令输出的文件描述符。您可以使用它为不允许标准输入的命令提供文件名,例如bash --rcfile
'. /etc/bash.bashrc; . ~/.bashrc; cd myproject; workon myvirtualenv'
:即时生成的 rcfile 的内容。这包含在 shell 接受常规用户输入之前执行的实际命令。
由于此命令使用仅在 bash 中可用的语法,因此只能从 bash shell 运行。以下稍微复杂一些的命令可在任何 shell 中运行:
urxvt -e bash -c "exec bash --rcfile <(echo '. /etc/bash.bashrc; . ~/.bashrc; cd myproject; workon myvirtualenv')"
这对于典型的启动命令来说更适合,例如在~/.xsessionrc
或中~/.xinitrc
。