如何防止命令退出后终端关闭?

如何防止命令退出后终端关闭?

我正在从启动脚本启动 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

相关内容