在vim中,我可以访问bash环境变量,例如$ PWD和$ PATH。我也想知道如何在vim中访问我的临时shell变量。
例如,假设我在终端中,并定义了一个变量foo="bar"
。然后,我输入vim并尝试使用以下命令:!echo $foo
访问此变量,但是它无法识别该变量。据我了解,每次调用bash命令时,vim都会启动一个新的shell,然后立即关闭它。是否可以在vim中使用与定义本地变量foo
相同的shell?
答案 0 :(得分:4)
不,您不能与它生成的子进程中的父Shell进行交互(没有该Shell的积极参与,这在当前情况下不可行/不可行),但是您可以导出变量,以使子进程中启动的新Shell可以访问它们。
运行
set -a
...即使没有明确的export
命令,也会使以后定义的任何变量自动导出到环境中。
由于(不同于C system()
函数),如果system()
(或SHELL
已在vim中运行),vim的SHELL=/bin/bash
会优先使用:set shell=/bin/bash
环境变量。 ,您也可以从vim调用导出的函数。也就是说,如果您定义函数并按如下所示导出它:
foo() { echo "bar"; }
export -f foo
...然后,您可以在vim内部用!foo
调用它。
但是,即使这样,它仍在新的临时shell实例中运行,而不是在原始父进程中运行。
答案 1 :(得分:0)
环境变量和外壳变量是两个完全不同的概念,但是当我们在bash中以相似的方式操作它们时,很容易感到困惑。
无论何时(通过fork)创建进程,它都可能包含一个环境,该环境由其父级在fork时给出。然后,子进程可以访问和修改其内容。作为用户如何完成此操作取决于程序:
:echo $foo
$ echo "$foo"
ENV['foo']
另一方面,程序可以为内部使用分配内存,但是值得注意的是,它经常会定义和使用变量。再一次,这取决于程序:
$ foo='bar'
分配一个变量,然后使用$ echo "$foo"
读取它foo='bar'
语法的变体,有时还带有类型声明等如您所见,bash 使用相同的语法来读取环境变量和其自己的私有变量,这可能会引起一些混乱。
从bash shell执行vim
时,环境从父进程(bash)复制到子进程(vim),但是bash的私有内存(包括您可能已定义的变量)不是。
因此,从子进程访问它们将需要父子进程之间的某种进程间通信机制。尽管从技术上讲可行,但该选项未在bash或vim中实现。
为使变量可以从vim(或任何分支的进程)访问,您需要将其存在于vim进程的环境中。
有几种选择:
$ export foo='bar'
:这将标记您的变量以导出到随后执行的命令的环境中。在大多数情况下,这就是您想要的。$ foo='bar' vim
:这会将变量添加到 this vim命令的环境中。对于疑难解答或单行代码非常有用。$ set -a
:正如您在bash manpage中所看到的,这标记了每个后续定义,以导出到后续命令的环境中。从本质上讲,这等效于在每个后续定义之前加上export
。该问题使用:!echo $foo
语法显示foo
的值,这是另一个用例。 !
实际上是一个转义序列,使您可以从vim执行shell命令。
但是,vim无法在父shell(您在其中执行vim
命令的shell)中执行任何操作,因此它在子进程中创建了一个新的bash shell,在其中执行了echo
,并且显示结果。
在当前情况下,结果大致相同,但是在其他情况下很容易产生误导,因此了解此处发生的情况很重要。
使用expand
的{{3}}允许查找变量::echo expand("$foo")
但是,它的工作方式完全不同。
如果不存在名为foo
的内部变量,vim将调用shell进行查找(类似于!
会执行的操作)。
此选项比环境查找慢 ,在大多数情况下不建议使用。
答案 2 :(得分:0)
如果您想在:substitute
命令中使用shell中的值,实际上有一种方法。
我不知道它是否可以解决您的需求,但是我们开始吧。
假设我们要用您的Mydir
代替PWD
:
:s/Mydir/\=expand($PWD)/g