目前,当我在 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 实际上以正确的方式完成了整个事情,请参阅此问题:
答案1
我想知道在来源方面写陈词滥调会更好,而不是在来源方面。 (如 C 头文件)
[[ "${_NAME_OF_THIS_LIBSCRIPT:-""}" == "yes" ]] && return 0
_NAME_OF_THIS_LIBSCRIPT=yes
这样,您就不需要每次获取脚本文件时都重复相同的样板,该文件应该包含在多个位置共享的内容。或者我错过了什么?说实话,我不是 bash 编程高手,所以我真的很想听取别人的见解。
答案2
今天早上,我从我的文件中移出了一堆个人信息bash_profile
,bashrc
并将它们添加到我称之为 的新文件中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.sh
with中的函数$ 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