Bash 将所有变量从一个shell脚本传递到另一个shell脚本?

Bash 将所有变量从一个shell脚本传递到另一个shell脚本?,bash,shell,Bash,Shell,假设我有一个名为test.sh的shell/bash脚本,其中包含: #!/bin/bash TESTVARIABLE=hellohelloheloo ./test2.sh 我的test2.sh如下所示: #!/bin/bash echo ${TESTVARIABLE} 这是行不通的。我不想把所有变量都作为参数传递,因为这太过分了 有不同的方法吗?您基本上有两种选择: 在执行第二个脚本之前,将变量设置为环境变量(export TESTVARIABLE) 编写第二个脚本,即。test2.s

假设我有一个名为
test.sh
的shell/bash脚本,其中包含:

#!/bin/bash

TESTVARIABLE=hellohelloheloo
./test2.sh
我的
test2.sh
如下所示:

#!/bin/bash

echo ${TESTVARIABLE}
这是行不通的。我不想把所有变量都作为参数传递,因为这太过分了


有不同的方法吗?

您基本上有两种选择:

  • 在执行第二个脚本之前,将变量设置为环境变量(
    export TESTVARIABLE
  • 编写第二个脚本,即
    。test2.sh
    ,它将在同一个shell中运行。这将使您可以轻松共享更复杂的变量,如数组,但也意味着其他脚本可以修改源shell中的变量
  • 更新:

    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.py
    
    #!/usr/bin/python
    
    import os
    
    print 'The message is:', os.environ['MESSAGE']
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    echo "[A] The message is: $MESSAGE"
    
    #!/bin/sh
    
    echo "[B] The message is: $MESSAGE"
    
    MESSAGE="goodbye"
    
    要使用
    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
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.py
    
    #!/usr/bin/python
    
    import os
    
    print 'The message is:', os.environ['MESSAGE']
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    echo "[A] The message is: $MESSAGE"
    
    #!/bin/sh
    
    echo "[B] The message is: $MESSAGE"
    
    MESSAGE="goodbye"
    
    b.sh:

    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.py
    
    #!/usr/bin/python
    
    import os
    
    print 'The message is:', os.environ['MESSAGE']
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    echo "[A] The message is: $MESSAGE"
    
    #!/bin/sh
    
    echo "[B] The message is: $MESSAGE"
    
    MESSAGE="goodbye"
    
    然后:

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

    a.sh:

    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.py
    
    #!/usr/bin/python
    
    import os
    
    print 'The message is:', os.environ['MESSAGE']
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    echo "[A] The message is: $MESSAGE"
    
    #!/bin/sh
    
    echo "[B] The message is: $MESSAGE"
    
    MESSAGE="goodbye"
    
    b.py:

    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.py
    
    #!/usr/bin/python
    
    import os
    
    print 'The message is:', os.environ['MESSAGE']
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    echo "[A] The message is: $MESSAGE"
    
    #!/bin/sh
    
    echo "[B] The message is: $MESSAGE"
    
    MESSAGE="goodbye"
    
    采购:

    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.py
    
    #!/usr/bin/python
    
    import os
    
    print 'The message is:', os.environ['MESSAGE']
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    echo "[A] The message is: $MESSAGE"
    
    #!/bin/sh
    
    echo "[B] The message is: $MESSAGE"
    
    MESSAGE="goodbye"
    
    取而代之的是,我们可以这样做:

    #!/bin/bash
    
    echo ${TESTVARIABLE}
    
    a.sh:

    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.py
    
    #!/usr/bin/python
    
    import os
    
    print 'The message is:', os.environ['MESSAGE']
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    echo "[A] The message is: $MESSAGE"
    
    #!/bin/sh
    
    echo "[B] The message is: $MESSAGE"
    
    MESSAGE="goodbye"
    
    b.sh:

    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.py
    
    #!/usr/bin/python
    
    import os
    
    print 'The message is:', os.environ['MESSAGE']
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    echo "[A] The message is: $MESSAGE"
    
    #!/bin/sh
    
    echo "[B] The message is: $MESSAGE"
    
    MESSAGE="goodbye"
    
    然后:

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

    a.sh:

    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.py
    
    #!/usr/bin/python
    
    import os
    
    print 'The message is:', os.environ['MESSAGE']
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    echo "[A] The message is: $MESSAGE"
    
    #!/bin/sh
    
    echo "[B] The message is: $MESSAGE"
    
    MESSAGE="goodbye"
    
    b.sh:

    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.py
    
    #!/usr/bin/python
    
    import os
    
    print 'The message is:', os.environ['MESSAGE']
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    echo "[A] The message is: $MESSAGE"
    
    #!/bin/sh
    
    echo "[B] The message is: $MESSAGE"
    
    MESSAGE="goodbye"
    
    然后:


    这同样适用于
    bash
    。它还可以方便地共享无法表示为环境变量的更复杂的数据(至少在没有负担的情况下),如数组或关联数组。

    实际上有一种比导出、取消设置或再次寻源更简单的方法(至少在bash中,只要您不介意手动传递环境变量):

    让a.sh去吧

    #!/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测试]$./a.sh
    哟,让我告诉你“眨眨我的丁当”,b.sh!
    我听到“我的叮当声”,哟

    神奇之处在于
    a.sh
    的最后一行,其中
    消息
    ,仅在调用
    /b.sh
    的持续时间内,从
    a.sh
    设置为
    secret
    的值。 基本上,它有点像命名参数/参数。不过,除此之外,它甚至适用于变量,如
    $DISPLAY
    ,它控制应用程序在哪个X服务器上启动


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

    除了致命错误的答案之外,还有一种方法可以将变量传递给另一个shell脚本

    上述建议的解决方案有一些缺点:

    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    export MESSAGE
    ./b.py
    
    #!/usr/bin/python
    
    import os
    
    print 'The message is:', os.environ['MESSAGE']
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    #!/bin/sh
    
    echo "The message is: $MESSAGE"
    
    #!/bin/sh
    
    MESSAGE="hello"
    
    . ./b.sh
    
    echo "[A] The message is: $MESSAGE"
    
    #!/bin/sh
    
    echo "[B] The message is: $MESSAGE"
    
    MESSAGE="goodbye"
    
  • 使用Export
    :这将导致变量超出其范围,这不是一个好的设计实践
  • 使用源代码
    :它可能会导致名称冲突或意外覆盖源代码为另一个文件的其他shell脚本文件中的预定义变量
  • 还有另一个简单的解决方案可供我们使用。 考虑到你所举的例子

    test.sh

    #!/bin/bash
    
    TESTVARIABLE=hellohelloheloo
    ./test2.sh "$TESTVARIABLE"
    
    #!/bin/bash
    
    echo $1
    
    #!/bin/bash
    echo in master.sh
    var1="hello world"
    sh slave1.sh $var1
    sh slave2.sh "$var1"
    echo back to master
    
    #!/bin/bash
    echo in slave1.sh
    echo value :$1
    
    #!/bin/bash
    echo in slave2.sh
    echo value : $1
    
    test2.sh

    #!/bin/bash
    
    TESTVARIABLE=hellohelloheloo
    ./test2.sh "$TESTVARIABLE"
    
    #!/bin/bash
    
    echo $1
    
    #!/bin/bash
    echo in master.sh
    var1="hello world"
    sh slave1.sh $var1
    sh slave2.sh "$var1"
    echo back to master
    
    #!/bin/bash
    echo in slave1.sh
    echo value :$1
    
    #!/bin/bash
    echo in slave2.sh
    echo value : $1
    
    输出

    hellohelloheloo
    
    另外,需要注意的是,如果传递多字字符串,则必须使用
    ”。 再举一个例子

    master.sh

    #!/bin/bash
    
    TESTVARIABLE=hellohelloheloo
    ./test2.sh "$TESTVARIABLE"
    
    #!/bin/bash
    
    echo $1
    
    #!/bin/bash
    echo in master.sh
    var1="hello world"
    sh slave1.sh $var1
    sh slave2.sh "$var1"
    echo back to master
    
    #!/bin/bash
    echo in slave1.sh
    echo value :$1
    
    #!/bin/bash
    echo in slave2.sh
    echo value : $1
    
    slave1.sh

    #!/bin/bash
    
    TESTVARIABLE=hellohelloheloo
    ./test2.sh "$TESTVARIABLE"
    
    #!/bin/bash
    
    echo $1
    
    #!/bin/bash
    echo in master.sh
    var1="hello world"
    sh slave1.sh $var1
    sh slave2.sh "$var1"
    echo back to master
    
    #!/bin/bash
    echo in slave1.sh
    echo value :$1
    
    #!/bin/bash
    echo in slave2.sh
    echo value : $1
    
    slave2.sh

    #!/bin/bash
    
    TESTVARIABLE=hellohelloheloo
    ./test2.sh "$TESTVARIABLE"
    
    #!/bin/bash
    
    echo $1
    
    #!/bin/bash
    echo in master.sh
    var1="hello world"
    sh slave1.sh $var1
    sh slave2.sh "$var1"
    echo back to master
    
    #!/bin/bash
    echo in slave1.sh
    echo value :$1
    
    #!/bin/bash
    echo in slave2.sh
    echo value : $1
    
    输出

    in master.sh
    in slave1.sh
    value :"hello
    in slave2.sh
    value :"hello world"
    

    之所以会发生这种情况,是因为

    中恰当地描述了一些原因。致命错误给出了一个简单的可能性:源代码是您的第二个脚本!如果您担心这第二个脚本可能会改变一些宝贵的变量,您可以始终在子shell中源代码:

    ( . ./test2.sh )
    
    括号将使源代码发生在子shell中,这样父shell就不会看到
    test2.sh
    可以执行的修改


    这里还应该明确提到另一种可能性:使用
    set-a

    从:

    -a
    :启用此选项时,应为执行赋值的每个变量设置导出属性;请参阅IEEE Std 1003.1-2001的基本定义卷。如果命令中的赋值位于实用程序名称之前,则在实用程序完成后,导出属性不应在当前执行环境中保持不变es,但在一个特殊内置实用程序之前导致导出属性在内置完成后保持不变的情况除外。如果命令中的赋值不在实用程序名称之前,或者如果赋值是getopts或read实用程序操作的结果,则导出属性应保持不变,直到变量这是不确定的

    从:

    -a
    :M