这使我感到不安,使我完全陷入困境。我觉得找到答案将有一些很好的学习机会,因此希望它是有意义的。
我使用Vim进行嵌入式C开发,并使用Arduino(使用Arduino Makefile)为业余爱好者进行了设置。我在构建项目中使用了:make
和一些快捷方式。
外部定义在项目级别Makefile中解析Arduino Makefile根目录:“ ARDMK_DIR = / usr / local / opt / arduino-mk”。这被定义为外壳程序(zsh)中的导出。这是奇怪的地方:
make
会提示项目构建良好:make -d
This program built for i386-apple-darwin11.3.0
Reading makefiles...
Reading makefile `Makefile'...
Reading makefile `/usr/local/opt/arduino-mk/Arduino.mk' (search path) (no ~ expansion)...
:make
时,定义就可以通过旧的安装来实现::make
This program built for i386-apple-darwin11.3.0
Reading makefiles...
Reading makefile `Makefile'...
Reading makefile `/usr/local/Cellar/arduino-mk/1.5.2/Arduino.mk' (search path) (no ~ expansion)...
Makefile:24: /usr/local/Cellar/arduino-mk/1.5.2/Arduino.mk: No such file or directory
我一生无法找到将ARDMK_DIR重新定义为'/usr/local/Cellar/arduino-mk/1.5.2'的位置。我尝试过的事情:
setlocal makeprg=echo\ $ARDMK_DIR\ &&\ make\ -d\
:echo在我的shell定义(/ usr / local / opt / arduino-mk)中返回,但是make
失败,并出现上述错误!:echo $ARDMK_DIR
:再次返回我的shell定义。ag
是ARDMK_DIR的主目录,唯一定义的位置是在我的shell导出中。从那以后,我的根目录就到了。 $ VIMRUNTIME也是一样makeprg
?!ARDMK_DIR
。一切都按预期找到。但是,当我在不同的系统上编译时,我不想这样做。在echo
和make
的实际执行之间的某些位置,正在重新定义ARDMK_DIR。为什么并且任何人都可以想到一种找出问题所在并加以解决的方法?
答案 0 :(得分:1)
Zsh具有多个来源的初始化文件。在外壳程序启动时,文件.zshenv
始终是源文件,而在交互式模式下启动外壳程序时,文件.zshrc
仅是源文件。
如果您在ARDMK_DIR
和.zshenv
中用不同的值定义变量.zshrc
,则当您与外壳进行交互时(输入),将使用.zshrc
中的值命令,启动Vim,...)。
但是,当Vim启动命令时,它将启动非交互式shell。在这种情况下,将仅源文件.zshenv
,因此您可以从该文件中获取值。
还有一个问题:
为什么以下命令首先回显正确的值,但是make
使用了错误的值?
:setlocal makeprg=echo\ $ARDMK_DIR\ &&\ make\ -d\
为了测试,我在strace
下启动了Vim。然后:
:set makeprg=echo\ $EDITOR
:make
在strace文件中,我找到了以下行:
execve("/usr/bin/zsh", ["/usr/bin/zsh", "-c", "echo vi 2>&1| tee /tmp/vdxR5DH/"...], [/* 86 vars */]) = 0
如您所见,Vim执行echo vi
,因此在调用shell之前它已经将环境变量$EDITOR
扩展为其值。
因此,上述问题的答案是,echo
命令回显了文本,而Vim插入了命令行,而make
命令从环境中获取了变量值。由于它是非交互式外壳,因此它是.zshenv
中的值。