避免多次获取脚本

避免多次获取脚本

目前,当我在 Mac 上打开终端时,它会自动调用:

source ~/.bash_profile

~/.bashrc然而,令我困惑的是,我的 shell 似乎没有继承或 的任何内容~/.profile。但这可能是典型的。

我有许多脚本可以使用source或继承.;如果我将这些调用放入~/.bash_profile,则可能需要一些时间来加载新的 shell 窗口,有时需要 3 或 4 秒,而且这会变得过时。我想有某种方法可以只获取这些脚本一次,并让我的~/.bash_profile文件以某种方式继承它。

请注意,从我的 ~/.bash_profile 调用 source ~/.bashrc 或 source ~/.profile 不是我想要做的,而且也可能是一个坏主意。这不是我想做的,因为它没有解决每个新 shell 加载缓慢的问题。

我添加了一些 echo 语句;每次我打开新的 bash 终端窗口时,都会记录以下内容:

starting to load /etc/profile
finished loading /etc/profile
starting to load bash_profile
finished loading bash_profile

这是有道理的,但令人沮丧的是 - 我真的需要在每次打开新 shell 时加载这些吗?为什么它不能做一些花哨的继承,这样我们就不必每次都重新加载所有内容?

我创建了一个视频来演示该问题。我经常使用 4 个终端应用程序:

terminal.app                  # misbehaves
iterm2                        # misbehaves
webstorm terminal emulator    # misbehaves
vscode terminal emulator      # behaves!

VSCode 实际上按照我想要的方式运行。我猜测它是通过在父 shell 中加载 ~/.bash_profile 来实现这一点的,并且只在 vscode 启动时执行一次。应用程序中的所有终端窗口都是该父 shell 的子 shell。

希望这个视频能够澄清这个问题: https://www.uselooom.com/share/4e62f0cb24434c4a83b8bd32844b596a

这是一个合法的问题 - 大多数终端应用程序都会错误地完成整个事情,但是,非常奇迹的是,微软的 VSCode 实际上以正确的方式完成了整个事情,请参阅此问题:

https://youtrack.jetbrains.com/issue/WEB-31390

答案1

我想知道在来源方面写陈词滥调会更好,而不是在来源方面。 (如 C 头文件)

[[ "${_NAME_OF_THIS_LIBSCRIPT:-""}" == "yes" ]] && return 0
_NAME_OF_THIS_LIBSCRIPT=yes

这样,您就不需要每次获取脚本文件时都重复相同的样板,该文件应该包含在多个位置共享的内容。或者我错过了什么?说实话,我不是 bash 编程高手,所以我真的很想听取别人的见解。

答案2

今天早上,我从我的文件中移出了一堆个人信息bash_profilebashrc并将它们添加到我称之为 的新文件中privaterc

在我的privaterc文件中我设置了这个变量:

PRIVATERC_RUN=yes 

现在在我的bash_profile我添加了这一行:

[[ $PRIVATERC_RUN != yes && -f ~/.privaterc ]] && source ~/.privaterc

这将导致privaterc仅在之前未在该 shell 中获取资源时才获取资源。


另外,对于您所看到的个人资料怪异,我在评论中链接的文章指出了以下有关 mac 的内容:

Mac OS X——一个例外

终端窗口准则的一个例外是 Mac OS X 的 Terminal.app,它默认为每个新终端窗口运行一个登录 shell,调用 .bash_profile 而不是 .bashrc。其他 GUI 终端仿真器可能会执行相同的操作,但大多数往往不会这样做。

答案3

在 rc 文件中放置一个唯一变量 - 长度为 1 个或多个字节 - 然后在获取 bash_profile 之前检查它的长度是否大于 0。

if [ ! X”” = X”$uniq_var” ] ; then . ~/.bash_profile ; fi

我只是在 MacOS 上将 bash 设置为登录 shell,并没有出现此问题。也许他们又改变了一些东西。

答案4

这是我的测试版本,基于 Hiroshi_U 的答案。

我想测试mylib.shwith中的函数$ source mylib.sh;sysLog Hey,如果我之后更改了某些内容并尝试从中获取更新的结果,则该函数将不是最新的。我必须取消设置_NAME_OF_THIS_LIBSCRIPT才能使其成为新的。由于$ echo $0会产生类似-sh和 的内容-bash,因此我进行测试以-确定它是在脚本文件中还是在 shell 下运行。

mylib.sh

#!/bin/sh

MY_BASE=$0
[[ "${_NAME_OF_THIS_LIBSCRIPT:-""}" == "yes" ]] && return 0
[[ "${MY_BASE:0:1}" != "-" ]] && _NAME_OF_THIS_LIBSCRIPT=yes

function sysLOG() {
    echo $1 $_NAME_OF_THIS_LIBSCRIPT
}

测试文件

#!/bin/sh

source /tmp/mylib.sh
sysLOG 1
source /tmp/mylib.sh
sysLOG 2
source /tmp/mylib.sh
sysLOG 3

$ test.sh;echo $_NAME_OF_THIS_LIBSCRIPT
1 yes
2 yes
3 yes

$ source mylib.sh;sysLog Hey;echo $_NAME_OF_THIS_LIBSCRIPT
Hey! yes

没有[[ "${MY_BASE:0:1}" != "-" ]] &&

$ source mylib.sh;sysLog Hey;echo $_NAME_OF_THIS_LIBSCRIPT
Hey! yes
yes

相关内容