首页 > 解决方案 > 如何使用 MAKEFILE 将环境变量从 shell 脚本导出到当前 shell 实例

问题描述

在我的 makefile 中,我想通过 .PHONY 语句调用一个 shell 脚本。在我的 shell 脚本中,我正在导出一个变量并期望它在当前的 shell 实例中被导出。使目标运行正常,但变量未反映在当前 shell 中。

生成文件

$ cat Makefile 
.PHONY: configure-mytest-path
configure-mytest-path:
        . ./scripts/test.sh

我通过 make 目标使用的 Shell 脚本

$ cat scripts/test.sh 
#!/bin/bash
set -x

export MYTESTPATH=/Users/myname/go/mytestpath

检查变量值

$ echo $MYTESTPATH

运行目标

$ make configure-mytest-path
. ./scripts/test.sh
++ export MYTESTPATH=/Users/myname/go/mytestpath
++ MYTESTPATH=/Users/myname/go/mytestpath

检查变量值。

$ echo $MYTESTPATH

我期待echo $MYTESTPATH应该打印/Users/myname/go/mytestpath,但它打印为空白。我错过了什么吗?或者这不是将变量导出到当前 shell 实例的方式?

感谢您的理解

标签: linuxshellmakefilegnu

解决方案


不可能做你想做的事。

进程的环境由其父进程创建并交给它。一旦子进程启动,它的环境就完全是它自己的了。它不能被它的父级修改,它也不能被它创建的任何子级修改。孩子们将拥有自己的环境副本并且可以更改它们,但它们对父母没有影响。

在你的makefile中,你有3个进程:你的shell(你正在输入make的地方),它启动make程序,然后make将启动一个新的shell来运行配方。

第三个程序根本无法修改第一个程序的环境。它甚至不能修改第二个程序(make)的环境。

修改第一个程序(您的外壳)环境的唯一方法是. ./scripts/test.sh 在该程序中使用(而不是运行make)。

如果你运行,./scripts/test.sh那么它也不会工作:这将运行一个新的 shell,新的 shell 将运行该脚本并设置环境变量,然后新的 shell 将退出,你的第一个 shell 仍然不会改变它的环境。

.命令是一个特殊的 shell 命令,意思是:不要启动一个新的 shell 来运行这个 shell 脚本;相反,在当前 shell中运行文件中包含的命令,就像您在 shell 提示符下键入它们一样。

在 bash 中,您可以将source其用作.和 type的别名,source ./scripts/test.h因为有些人发现它更容易理解:它们的意思相同。

您还可以创建一个 shell 函数或 shell 别名来执行此操作,因为它们也在同一个 shell 进程中运行,而不是在子进程中。

但是,没有办法通过 makefile 或运行 make 来完成。


推荐阅读