使用vim外部命令调用bash函数

7

我经常使用vim的:!外部命令函数,通常将%作为参数提供给shell命令。例如:

:!psql -f %

我在我的.bashrc文件中有许多我使用的bash shell函数。例如:

psql-h1 () 
{ 
    /usr/bin/psql -hh1 -d mydb "$@"
}

这些bash函数在vim的:!命令下不可用。有没有办法使它们可用?

你确定你在vim内使用的是bash吗?运行:!echo $0是否输出bash - hnefatl
两种解决方案:1. :help 'shellcmdflag',2. 将您的函数转换为实际脚本并将它们放在 $PATH 中的某个位置。 - romainl
4个回答

6

导出你的函数。也就是说:

psql-h1() { /usr/bin/psql -hh1 -d mydb "$@"; }

export -f psql-h1  ### <-- THIS RIGHT HERE

这会使它们对任何作为子进程运行的 bash 副本可用,即使是非交互式 shell,因此不会读取 .bashrc


太好了,就是这个。我知道你将环境变量导出到子进程中,但我不知道关于bash函数的事情。 - Jeremy
基本上是一样的东西 - 导出函数只是一个带有不寻常名称和函数代码作为值的导出变量;bash扫描环境以查找与约定匹配的任何名称,并将它们解析为代码。这个特性是双刃剑 - 它是导致Shellshock的原因。 - Charles Duffy

3

如果你的函数无法到达Vim(例如在中间存在非Bash shell,可以参考此处),则可以选择另一种方法,即指示Vim启动一个交互式 shell,以便读取你的.bashrc。只需通过Vim的:help 'shellcmdflag'-i标志传递给Bash。

:set shcf=-ic

0

这个答案假设你的vim实际上没有使用bash来调用远程命令 - 你可以通过在vim中运行:!echo $0来测试。

特别针对vim,添加:

set shell=/bin/bash

添加到你的.vimrc文件中。


通常情况下,我发现有两种策略有时可以用来尝试让其他程序调用我喜欢的 shell:
export SHELL=/bin/bash

例如在 .profile 文件中,或者:

ln -fsn /bin/bash /bin/sh

这会更新sh符号链接,将其指向bash

在许多系统上(当然包括Ubuntu),/bin/sh是一个符号链接,指向一个与sh兼容的shell(如bash),而不是sh shell本身。鉴于此事实,一些程序(我在GHC中看到了这种行为)似乎调用/bin/sh,因此更改其指向将导致程序使用bash


确保shell是bash是必要的,但不足以保证:没有交互标志的bash副本(也就是那些[[ $- = *i* ]]不为真的副本)不会读取.bashrc - Charles Duffy
另外,将/bin/sh链接到bash并不意味着在调用时会得到bash语法 - 当以该名称调用时,bash可执行文件以POSIX兼容模式运行。在该模式下仍然可以使用一些扩展功能,但绝不是全部。 - Charles Duffy

0

被接受的答案对我没用。我打算按照其他地方建议的设置shcf:

:set shcf=-ic

但另一种解决方案是

!source ~/.bashrc && psql ...

很遗憾,目前没有解决方案可以使我正在创建的命令的自动补全正常工作。(建议的自动补全是当前目录中文件的名称,而不是我在 .bashrc 中指定的那些)

complete -F _generate_foo_completions foo

如果接受的答案不起作用,我会首先开始调试的地方是查看vim是否启动了与您在调用之前执行“export”相同的shell版本。在Shellshock之前和之后的bash版本中,使用不同的格式来存储导出函数到环境变量中,如果一个shell根本不是bash而是zsh或其他什么东西,那么这就是您的问题所在。 - Charles Duffy
如果source命令能够正常工作,那么这告诉我们vim没有启动/bin/sh(至少在提供dash或其他非bash shell的平台上不是),但不幸的是,“不起作用”并不能提供很多调试细节。 - Charles Duffy
环境中是否有变量名称不符合规范的清理过程是另一个需要查看的地方;Ingo的链接详细介绍了这个问题。 - Charles Duffy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接