0
votes

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

1

1 Answers

3
votes

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.