问题描述
在我的makefile文件中,我想通过.PHONY语句调用Shell脚本.在我的shell脚本中,我正在导出一个变量,并希望在当前的shell实例中将其导出.使目标运行正常,但该变量不会反映在当前外壳中.
Makefile
$ cat Makefile.PHONY:configure-mytest-pathconfigure-mytest-path:../scripts/test.sh
我通过make目标使用的Shell脚本
$ cat scripts/test.sh#!/bin/bash设置-x导出MYTESTPATH =/Users/myname/go/mytestpath
检查变量值
$ echo $ MYTESTPATH
运行目标
$ make configure-mytest-path../scripts/test.sh++导出MYTESTPATH =/Users/myname/go/mytestpath++ MYTESTPATH =/用户/myname/go/mytestpath
检查变量值.
$ echo $ MYTESTPATH
我希望 echo $ MYTESTPATH
应该打印/Users/myname/go/mytestpath
,但它会打印空白.我想念什么吗?还是这不是将变量导出到当前shell实例的方法?
感谢理解
无法做您想做的事.
进程的环境由其父级创建并移交给它.子进程启动后,其环境将完全由其自己决定.它不能由其父级修改,也不能由其创建的任何子级修改.孩子们将拥有自己的环境副本,并且可以更改它们,但对父母没有任何影响.
在您的makefile中,您有3个过程:您的shell(您在其中键入make),它启动make程序,然后make将启动一个新的shell,它将运行配方.
第三个程序根本无法修改第一个程序的环境.它甚至无法修改第二个程序(make)的环境.
修改第一个程序(您的外壳)环境的 only 方法是使用../scripts/test.sh
在该程序中(而不是运行 make
).
如果您运行 ./scripts/test.sh
,那么它也将不起作用:它将运行一个新的shell,新的shell将运行该脚本并设置环境变量,然后新的外壳程序将退出,您的第一个外壳程序仍将保持不变.
.
命令是一个特殊的shell命令,它意味着:不要启动新的shell来运行该shell脚本;而是在当前shell中运行文件 中包含的命令,就像在shell提示符下键入命令一样.
在bash中,您可以使用 source
作为的别名.
并键入 source ./scripts/test.h
,因为有人发现更容易理解:它们含义相同.
您还可以创建一个shell函数或shell别名来执行此操作,因为它们也运行在同一个shell进程中,而不是在子进程中.
但是,无法通过makefile或运行make来实现.
In my makefile, I would like to call a shell script through .PHONY statement. In my shell script i am exporting a variable and expecting it to be exported in the current shell instances. Make target runs fine but the variable does not reflect in the current shell.
Makefile
$ cat Makefile
.PHONY: configure-mytest-path
configure-mytest-path:
. ./scripts/test.sh
Shell script which i am using through the make target
$ cat scripts/test.sh
#!/bin/bash
set -x
export MYTESTPATH=/Users/myname/go/mytestpath
Checking the variable value
$ echo $MYTESTPATH
Running the target
$ make configure-mytest-path
. ./scripts/test.sh
++ export MYTESTPATH=/Users/myname/go/mytestpath
++ MYTESTPATH=/Users/myname/go/mytestpath
Checking the variable value.
$ echo $MYTESTPATH
I am expecting echo $MYTESTPATH
should print /Users/myname/go/mytestpath
but it prints blank. Did i miss anything ? or this is not the way of exporting variable to the current shell instance ?
Thanks for understanding
It is not possible to do what you want.
A process's environment is created and handed to it by its parent. Once the child process starts, its environment is completely its own. It cannot be modified by its parent and it also cannot be modified by any children that it creates. The children will have their own environment copies and can change those, but they have no impact on the parent.
In your makefile, you have 3 processes: your shell (where you're typing make), which starts the make program, then make will start a new shell which will run the recipe.
There's simply no way for that third program to modify the environment of the first program. It can't even modify the environment of the second program (make).
The only way to modify the environment of the first program (your shell) is to use the . ./scripts/test.sh
in that program (instead of running make
).
If you run ./scripts/test.sh
then it also won't work: that will run a new shell, the new shell will run that script and set the environment variable, then the new shell will exit and your first shell will still not have its environment changed.
The .
command is a special shell command that means: don't start a new shell to run this shell script; instead, run the commands contained in the file in the current shell, as if you'd typed them in at the shell prompt.
In bash, you can use source
as an alias for .
and type source ./scripts/test.h
because some people find it easier to understand: they mean the same thing.
You can also create a shell function or shell alias to do it, because those also run in the same shell process, not in a child process.
But, there's no way to do it through a makefile or by running make.
这篇关于如何使用MAKEFILE将环境变量从shell脚本导出到当前的shell实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!