我试图访问上一个命令声明的变量(在Makefile中)。
这里是Makefile
:
all:
./script1.sh
./script2.sh
这里是声明我想要访问的变量的脚本,script1.sh
:
#!/usr/bin/env bash
myVar=1234
此处的脚本试图访问之前定义的变量script2.sh
:
#!/usr/bin/env bash
echo $myVar
不幸的是,当我运行make
时,myVar
无法访问。还有另外一种方法吗?感谢。
答案 0 :(得分:3)
Make将在自己的shell中运行每个shell命令。当shell退出时,它的环境就会丢失。
如果您希望下一个脚本中的变量可用,那么有一些构造可以执行此操作。例如:
all:
( . ./script1.sh; ./script2.sh )
这会导致Make启动一个shell来处理这两个脚本。
另请注意,您需要导出变量,以便在第二个脚本中显示变量;未导出的变量仅适用于本地脚本,而不适用于它启动的子shell。
更新(根据Kusalananda的评论):
如果希望shell命令填充MAKE变量而不仅仅填充环境变量,则可能有一些选项取决于您正在运行的Make版本。例如,在BSD make和GNU make中,你可以使用"变量赋值修饰符"包括(来自BSD制作手册页):
!= Expand the value and pass it to the shell for execution and
assign the result to the variable. Any newlines in the result
are replaced with spaces.
因此,使用BSD make和GNU make,你可以这样做:
$ cat Makefile
foo!= . ./script1.sh; ./script2.sh
all:
@echo "foo=${foo}"
$
$ cat script1.sh
export test=bar
$
$ cat script2.sh
#!/usr/bin/env bash
echo "$test"
$
$ make
foo=bar
$
请注意,script1.sh
不包含任何shebang,因为它是 sourced ,因此在调用shell中运行,无论是什么。这使得shebang线只是一个评论。如果您使用的是默认shell为POSIX但不是bash(如Ubuntu,Solaris,FreeBSD等)的系统,这应该仍然有效,因为POSIX shell都应该理解导出变量的概念。
答案 1 :(得分:1)
两个单独的脚本调用创建了两个独立的环境。第一个脚本在其环境中设置变量并退出(环境丢失)。第二个脚本在其环境中没有该变量,因此它输出一个空字符串。
除了父shell的环境与其子shell之间的环境之外,环境变量不能在环境之间传递(不是相反)。传递到子shell的变量只是 那些父shell具有export
- ed的变量。因此,如果第一个脚本调用了第二个脚本,则会输出该值(如果它是export
- 在第一个脚本中编辑)。
在shell中,您将source
第一个文件在当前环境中设置变量(然后export
!)。但是,在Makefile中,它有点棘手,因为没有方便的source
命令。
相反,您可能需要阅读this StackOverflow question。
根据@ ghoti的回答编辑:@ghoti有一个很好的解决方案,但我会在这里留下我的答案,因为它更详细地解释了环境变量以及我们可以做些什么,而不是在环境之间传递它们。