在两个独立的shell脚本之间共享变量

时间:2016-04-04 03:51:40

标签: bash shell

我正在尝试从一个脚本导出一个变量并在另一个脚本中使用它,但是这个变量没有被导出可能是什么问题

将此视为script1

#!/bin/sh
export x=19
exit 0

将此视为script2

#!/bin/sh
echo "x="${x}
exit 0

我正在执行它们作为两个独立的脚本,如

desktop:~/Desktop/Trail_Programs$ sh script1.sh
desktop:~/Desktop/Trail_Programs$ sh script2.sh

,输出

desktop:~/Desktop/Trail_Programs$ sh script2.sh 
x=

4 个答案:

答案 0 :(得分:2)

来自source

script1.sh script2.sh

script2.sh开头(在shebang之后),添加:

source /path/to/script1.sh

答案 1 :(得分:2)

请记住,脚本可能从不影响其父级环境。 从不表示从不。遵循规则:

#!/bin/bash
export x=19
exit 0

对环境有 NO 影响,但未设置x=anythingexport只会影响从该脚本中创建的子shell 的环境。例如,使用您的脚本,将其称为exp.sh

#!/bin/bash
export x=19
./script2.sh
exit 0

并且script2.sh你有:

echo "x = $x"

然后,只有这样,你会得到:

$ bash exp.sh
x = 19

这只是规则...

答案 2 :(得分:1)

David C. Rankin's helpful answer解释了为什么您的代码无效。

注意:
只有在修改您使用的脚本不是一个选项时才应使用以下解决方案(如果您想了解采购和ad-hoc环境变量,解决方案也可能是您感兴趣的。)
否则,请参阅底部讨论的解决方案。 功能

要解决您的问题,您可以尝试以下方法:

x=$(trap 'printf %s "$x"' EXIT; . script1.sh >/dev/null) sh script2.sh

但请注意:

  • script1.sh必须由您的当前 shell执行,该shell可能是也可能不是sh
  • script1.sh的stdout输出被抑制,因为必须确保printf %s "$x"是命令替换($(...))内子shell产生的唯一stdout输出。
  • 此方法仅限于单个变量(尽管可以扩展为输出多个变量的值,然后调用脚本必须将其解析回单个值)。

. script1.sh sources 子shell中的脚本,这意味着子shell在其自己的环境中直接执行script1.sh,因此在执行后会看到脚本的变量它(这意味着它会看到$x,即使它没有导出)。

trap 'printf %s "$x"' EXIT设置退出陷阱;即子shell退出时执行的代码,在本例中为printf %s "$x",它只输出感兴趣变量的值。
请注意,即使$x由于script1.sh语句而终止,也必须采用此方法来确保打印exit的值;由于子script1.sh ,因此exit退出整个子shell。

x=$(...)捕获该值,并通过预先命令sh script2.sh,有效地使得$x成为环境 script2.sh然后看到的变量。

对于源代码来说,通常存在问题:

  • 脚本修改或创建的所有变量以及脚本执行的对shell环境的任何更改将影响调用shell。
  • 如果此类脚本执行exit,它们也将退出调用shell。

如果由于某种原因无法修改所涉及的脚本,则上述解决方案是最佳选择,因为它绕过了这些问题,尽管有一些限制。

更强大的通用解决方案(修改所需的脚本):

让脚本设置感兴趣的环境变量本身调用另一个脚本是正确的解决方案,如David's answer所示。

如果脚本确实需要作为 peers 运行,则需要通过文件传递值:让设置感兴趣的变量的脚本将其值写入一个(临时)文件,让另一个脚本读取该文件:

script1.sh

#!/bin/sh
export x=19
# Write to temp. file named for the *parent* process ID.
# Since both script calls will have the same parent process, this 
# allows you to avoid a static filename subject to name collisions.
printf %s "$x" > /tmp/x.$PPID

script2.sh

#!/bin/sh
# Read the value of $x from the temp. file, then delete the file.
x=$(cat /tmp/x.$PPID) && rm /tmp/x.$PPID
echo "x=${x}"

答案 3 :(得分:0)

假设您的文件addListener(new InputListener() { @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { setActiveSprite(row, column, colour); System.out.println("clicked" + "row :" + row + "column" + column); return false; } }); public void setActiveSprite(int r, int c, int colour){ System.out.print(colour); if (!(gf.activeTile.colour==0)){ gf.swapTiles(r, c, colour); gf.activeTile.colour=0; } else { gf.activeTile.setAll(r, c, colour); } } public void swapTiles(int r, int c, int colour) { gameField[activeTile.row][activeTile.column].addAction(Actions.moveTo( (40 + ((gameField[r][c].getHeight() * c) + (10 * c))), (200 + (gameField[r][c].getWidth() * r)), 0.5f)); //setting the new position of clicked tile gameField[r][c].addAction((Actions.moveTo( (40 + ((gameField[r][c].getHeight() * activeTile.column) + (10 * activeTile.column))), (200 + (gameField[r][c].getWidth() * activeTile.row)), 0.5f))); Tile Temp = gameField[activeTile.row][activeTile.column]; gameField[activeTile.row][activeTile.column] = gameField[r][c]; gameField[activeTile.row][activeTile.column].row = activeTile.row; gameField[activeTile.row][activeTile.column].column = activeTile.column; gameField[r][c] = Temp; gameField[r][c].row = r; gameField[r][c].column = c; } 包含以下内容

tobeincluded1

和文件#this file tobeincluded1 will be included in master x=16 包含以下内容

tobeincluded2

您可以使用#this file tobeincluded2 will be included in master y=21 .添加上述文件,如下所示:

source