我想知道是否有任何方法可以在我的启动文件中放入一些东西,这会导致在显示第一个提示后获取其他文件。
我更喜欢不依赖钩子的方法,如preexec
,precmd
或periodic
钩子。(我正在使用 zsh,但我知道人们已经编写了代码来将这些代码添加到 bash,通过一些巧妙的 hacktrap
或类似的东西。)
我非常简单的第一个测试(我没想到它会起作用,但我觉得有必要尝试一下,只是为了看到精确的结果)将它添加到我的.zshrc
,
{ sleep 100 && export VARIABLE_SET=1 } &
然后在shell加载后执行这个,在100秒之前和之后都过去了:
echo $VARIABLE_SET
当然,它(以及我能想到的每一种排列方式)都失败了,并且没有提供关于如何做到这一点的有希望的线索。
我希望启动文件中的某些内容可以触发影响 shell 的采购,即使它在第一个提示符下没有立即可用。我想找到一种方法来延迟“昂贵”的采购,并让提示迅速出现,因为许多使启动文件膨胀的东西都是不经常需要的东西。
我希望找到一种比使用钩子更简单的方法(但我已经使用钩子创建了一个概念验证precmd
,以防没有其他方法是可能的)。
你不能使用这个
{...} &
想法,因为它&
会导致东西被放在一个子shell中;在那里设置的变量不会影响父级。因此,我们可以将设置写入临时文件并将其读入父级。
一种方法可能是使用 DEBUG 陷阱。
未经过全面测试,但可能类似于
DEBUG 陷阱通常在命令执行后调用。
所以
如果您正在寻找一个
.env
文件来加载环境变量,那么dotenv可以帮助您。你总是可以使用
sched
. 添加到您的~/.zshrc
并且
~/.zsh/more-stuff
将在启动后 30 秒(或在 30 秒后的下一个提示处)获取。正如您所发现的,在后台运行命令
&
会将它们放在子shell中,并且子shell不能更改父进程的变量/环境变量。(这句话中的“不能”应该读作“变通方法很丑”。)因此,您需要
source
在当前 shell 中执行该命令。我将在下面列出几个选项。他们都没有完全回答你提出的问题,但他们似乎为你试图解决的实际问题提供了解决方案。
zsh-defer
(zsh 脚本).zshrc
:可以通过重复调用来提示任意数量的命令(
source .zshrc.2
等) 。source .zshrc.3
zsh-defer
好处:处理一些
zinit
不会的边缘情况。比sched
.性能:
zsh-defer
本身最多应该在几毫秒内加载。实现:
zle
从(zsh 的行编辑器)执行命令。zsh
zsh/sched
模块(正如@StéphaneChazelas 之前的回答所建议的那样)
简单直接。
.zshrc
:... &>/dev/null || ...
部分:如果不可用,或者因sched
错误退出,则文件会立即被源化,假设这总比没有好。详细信息
sched
:请参阅zsh 的文档。缺点:
Yearly check: do <evil thing>? [y/N]
如果在您键入命令时延迟命令意外要求用户输入 (" "),则可能会导致意外输入性能:命令
sched
执行最多需要几毫秒。使用带有即时提示的powerlevel10k提示
无需额外工作 - 随心所欲
.zshrc
;在处理过程中,提示将被加载并准备好进行交互(有一些警告).zshrc
。性能:从 shell 开始处理后大约 10 毫秒内应该可以看到提示
.zshrc
。实现:各种 zsh 功能和技巧。需要额外注意,例如在执行命令时重定向(和缓冲)标准输入,以避免意外输入。
插件管理器
zinit
zinit
您可以使用延迟zinit ice wait
执行任何命令,例如 source-ing 文件。zinit
可以仅用于该功能,无需将其用作插件管理器,并且不会与其他插件管理器(如果有)相互干扰。原版
zdharma/zinit
不再维护,但这些分叉是:我不认为长时间运行的命令会阻塞 shell,但我自己还没有测试过。
性能:在我的系统上,
zinit
它本身在大约 10 毫秒内加载,或者 5 毫秒没有完成。实现:
zinit
向 中添加一个 shell 函数zsh/sched
,该函数在被调用时立即将自身添加回表中,除此之外,还使用zsh 钩子和其他 zsh 功能sched
执行用户设置的命令。zsh-async
图书馆也可能有用 - 为了完整性而提及。
是一个小型通用库,用于在 zsh 中运行异步任务。但是,它将在单独的进程中运行它们,该进程将无法在父 shell 中设置环境变量。我相信对此有简单的解决方法,通过分配一个回调函数,该函数应该允许在父 shell 中执行结果。
优点:使用相当广泛,并积极维护了八年。
实现:用于
zsh/zpty
启动执行延迟命令的伪终端。推荐阅读
romkatv(
zsh-defer
和powerlevel10k的作者)关于分阶段 zsh 启动/lazy-loading/deferred 执行的一般想法和建议。关于外壳加载性能的额外常见问题解答
问:我可以编译
.zshrc
成 wordcode 以使其执行得更快吗?答:理论上是可能的,但很容易引入别名问题、错过重新编译等问题。不建议。
问:我现在了解可能出现的问题。我还是想试试这个。
A:不,真的,你没有。