我有一个文件 hadnodes.conf (为 AWS 虚拟机设置节点 IP 地址)
> ls -lista hadnodes.conf
7733498 4 -rwxrwxrwx. 1 pol pol 141 Feb 20 08:05 hadnodes.conf
内容(非真实IP):
> more hadnodes.conf
#!/bin/bash
export NAME_NODE=18.202.25.99
export DATA_NODE_1=52.30.117.99
export DATA_NODE_2=34.248.153.99
export DATA_NODE_3=52.17.111.99
另一个脚本文件setnodes
> ls -lista setnodes
7733504 4 -rwxrwxr-x. 1 pol pol 92 Feb 20 09:59 setnodes
内容:
> more setnodes
#!/bin/bash
source /home/pol/dcu/ca675_cloud_technologies/assignment_1/nodes/hadnodes.conf
现在,如果我输入,我就可以让 setnodes 工作
source /path/to/setnodes
但如果我跑步就不会
. /path/to/setnodes
但如果我只运行 > setnodes (作为可执行脚本),变量不会接受 - 即 $NAME_NODE、DATA_NODE_1 和 c 未定义。我已将相关目录放入 $PATH 中,并且正在发生制表符补全,因此并不是看不到脚本。命令“">which setnodes”也将其显示在正确的目录中。
我还尝试在 setnodes 中使用“exec”来运行我的 hadnodes.conf 脚本(如所述这里)但无济于事。
我想知道我在“链接”(顺序运行)bash 脚本方面缺少什么,以便脚本“N”中的环境变量沿着链向上传递到调用 shell/环境(脚本 0)。
答案1
我想知道我在“链接”(顺序运行)bash 脚本方面缺少什么,以便脚本“N”中的环境变量沿着链向上传递到调用 shell/环境(脚本 0)。
你忽略了一个事实:你不能这样做。不存在所谓的“环境”,而是每个进程都有自己的环境。从技术上讲,环境只是从父进程传递到子进程(或者实际上,从调用exec*()
被执行程序的程序)传递的一组字符串。没有办法“向上”传递环境变量,也没有办法在没有程序本身支持的情况下修改正在运行的程序的环境。
获取脚本(使用.
或source
)实际上并不在单独的进程中运行该脚本,而是调用 shell 本身在与运行外部脚本相同的上下文中读取并处理它。
所以如果我们有一个脚本a.sh
export FOO=abcd
然后运行将在“父”shell 环境中. a.sh
设置变量。FOO
但./a.sh
像往常一样跑步不会,也不可能。
“向上”传递变量赋值的一种方法是输出 shell 命令来设置它们,然后eval
在“父”shell 中运行它们。就是这样ssh-agent
,shell 中的实现将是这样的 ( b.sh
):
#!/bin/sh
# do something else here, but don't produce output
echo 'export FOO=abcd'
现在,我们运行,然后父 shell 将执行从命令替换接收到的eval "$(./b.sh)"
命令。export FOO=abcd
不过,如果子程序是 shell 脚本,那么按照上面的方式获取它可能会更容易。
当然,当您谈论链接时,您可以在一个 shell 中设置变量,然后调用另一个 shell,然后调用第三个 shell:
$ cat c1.sh
#!/bin/sh
export BAR=abcd
./c2.sh
$ cat c2.sh
#!/bin/sh
echo "$BAR"
现在,运行c1.sh
将运行c2.sh
,这将输出abcd
,因为 的值是从to BAR
“向下”继承的。c1.sh
c2.sh