假设我有一个名为test.sh的shell / bash脚本:

#!/bin/bash

TESTVARIABLE=hellohelloheloo
./test2.sh

我的test2.sh是这样的:

#!/bin/bash

echo ${TESTVARIABLE}

这行不通。我不想将所有变量作为参数传递,因为这是多余的。

还有别的办法吗?


当前回答

另一个选项是使用eval。这只适用于字符串是可信的。第一个脚本可以回显变量赋值:

回声“VAR = myvalue "

然后:

Eval $(./first.sh) ./second.sh

当您想要为其设置环境变量的第二个脚本不在bash中,并且您也不想导出变量时,这种方法特别有用,这可能是因为它们很敏感,您不想让它们持久保存。

其他回答

你基本上有两个选择:

在执行第二个脚本之前,将该变量设置为环境变量(export TESTVARIABLE)。 来源第二个脚本,即。Test2.sh和它将在同一个shell中运行。这将允许您轻松地共享更复杂的变量(如数组),但也意味着其他脚本可以修改源shell中的变量。

更新:

使用export来设置一个环境变量,你可以使用一个已经存在的变量:

A=10
# ...
export A

这应该在bash和sh中都可以工作。bash还允许它像这样组合:

export A=10

这也适用于我的sh(恰好是bash,你可以使用echo $SHELL检查)。但我不相信这在所有sh中都能保证工作,所以最好安全地将它们分开。

以这种方式导出的任何变量都将在你执行的脚本中可见,例如:

a.sh:

#!/bin/sh

MESSAGE="hello"
export MESSAGE
./b.sh

b.sh:

#!/bin/sh

echo "The message is: $MESSAGE"

然后:

$ ./a.sh
The message is: hello

这两个脚本都是shell脚本,这也是偶然的。环境变量可以传递给你执行的任何进程,例如,如果我们使用python来代替它,它可能是这样的:

a.sh:

#!/bin/sh

MESSAGE="hello"
export MESSAGE
./b.py

b.py:

#!/usr/bin/python

import os

print 'The message is:', os.environ['MESSAGE']

采购:

相反,我们可以这样做:

a.sh:

#!/bin/sh

MESSAGE="hello"

. ./b.sh

b.sh:

#!/bin/sh

echo "The message is: $MESSAGE"

然后:

$ ./a.sh
The message is: hello

这或多或少直接“导入”b.sh的内容,并在同一个shell中执行它。注意,我们不需要导出变量来访问它。这将隐式地共享您拥有的所有变量,并允许其他脚本在shell中添加/删除/修改变量。当然,在这个模型中,两个脚本应该使用相同的语言(sh或bash)。举个例子,我们可以来回传递消息:

a.sh:

#!/bin/sh

MESSAGE="hello"

. ./b.sh

echo "[A] The message is: $MESSAGE"

b.sh:

#!/bin/sh

echo "[B] The message is: $MESSAGE"

MESSAGE="goodbye"

然后:

$ ./a.sh
[B] The message is: hello
[A] The message is: goodbye

这在bash中同样有效。它还可以方便地共享无法表示为环境变量的更复杂的数据(至少不需要您做一些繁重的工作),如数组或关联数组。

实际上,有一种比导出和取消设置或再次获取更简单的方法(至少在bash中是这样,只要你愿意手动传递环境变量):

随他去吧

#!/bin/bash
secret="winkle my tinkle"
echo Yo, lemme tell you \"$secret\", b.sh!
Message=$secret ./b.sh

b.sh是

#!/bin/bash
echo I heard \"$Message\", yo

观察到的输出为

[rob@Archie test]$ ./a.sh 哟,让我告诉你"去我的丁丁",混蛋! 我听到了"撸我的丁丁

神奇之处在于a.h sh的最后一行,其中Message仅在调用./ b.h sh期间被设置为a.h sh的secret值。 基本上,它有点像命名参数/参数。不仅如此,它甚至还适用于$DISPLAY这样的变量,用于控制应用程序在哪个X Server中启动。

记住,环境变量列表的长度不是无限的。在我使用相对普通内核的系统上,xargs——show-limits告诉我参数缓冲区的最大大小是2094486字节。从理论上讲,如果您的数据大于此值(管道,有人吗?),则使用shell脚本是错误的。

另一个选项是使用eval。这只适用于字符串是可信的。第一个脚本可以回显变量赋值:

回声“VAR = myvalue "

然后:

Eval $(./first.sh) ./second.sh

当您想要为其设置环境变量的第二个脚本不在bash中,并且您也不想导出变量时,这种方法特别有用,这可能是因为它们很敏感,您不想让它们持久保存。

另一种更简单的方法是使用命名管道。命名管道提供了一种在不同进程之间同步和发送消息的方法。

A.bash:

#!/bin/bash
msg="The Message"
echo $msg > A.pipe

B.bash:

#!/bin/bash
msg=`cat ./A.pipe`
echo "message from A : $msg"

用法:

$ mkfifo A.pipe #You have to create it once
$ ./A.bash & ./B.bash # you have to run your scripts at the same time

B.bash将等待消息,一旦A.bash发送消息,B.bash将继续其工作。

在Bash中,如果你在子shell中导出变量,使用括号,你可以避免泄漏导出的变量:

#!/bin/bash

TESTVARIABLE=hellohelloheloo
(
export TESTVARIABLE    
source ./test2.sh
)

这样做的好处是,在你从命令行运行脚本之后,你不会看到$TESTVARIABLE泄露到你的环境中:

$ ./test.sh
hellohelloheloo
$ echo $TESTVARIABLE
                            #empty! no leak
$