传递参数以在孙子进程中使用

传递参数以在孙子进程中使用

我有一个参数列表和三个进程:

bash_script -> child -> grandchild

参数列表针对的是孙子。我可以修改所有三个进程。祖父脚本为自己获取一个参数。

以下是将剩余参数传递给孙子的正确方法吗?

#!/usr/bin/env bash
# This is the grandfather    
first_arg="$1"
shift 1;

export MY_ARGS="$@"

我稍后在子进程中“传播”环境变量,作为调用孙子进程的命令的一部分,如下所示:

grandchild --foo "$MY_ARGS"  # append $MY_ARGS as arguments to foo

答案1

在脚本中,不应将数组降级为字符串。环境变量及其值是一个简单的key=value对,其中keyvalue都是字符串。将位置参数降级为简单的字符串(通过连接)将很难保持它们之间的分离,并且当您最终想要使用它们时很难正确引用它们。

相反,传递您想要传递给命令行上的下一个脚本的位置参数(命令行参数)。

#!/bin/bash

first_arg=$1
shift

# later ...

./my_other_script "$@"

在另一个脚本中:

#!/bin/bash

# use "$@" here
foo --bar "$@"

答案2

编辑:看来你不能在 bash 中导出数组。您可能需要导出一个设置数组或类似内容的函数。

您应该使用数组,否则带有空格的参数将扩展到多个单词。

export MY_ARGS=("$@")


foo --bar "${MY_ARGS[@]}"

答案3

我不确定为什么人们对这个问题感到困惑,但也许这个问题令人困惑,这对我来说似乎很有效:

my_args_array=("$@")
export MY_ARGS="${my_args_array[@]}"

然后我们只需MY_ARGS像这样使用:

foo --bar $MY_ARGS

笔记正如@Kusalananda 指出的:这将失败如果原始参数中有空格。在这种情况下,最好使用$@, 而不是环境变量通过子进程传递参数。

答案4

一般的答案是这样的。您可以使用以下方式传递参数:

  • 命令行位置参数
  • 环境变量
  • 您的操作系统上可用的任何 IPC(进程间通信)

只关注前两个,

  • 位置参数是最自然的方式。这涉及 的可能编辑和进一步传输"$@",它代表所有当前定义的位置参数。这必须在流程层次结构的所有阶段上完成。
  • 环境变量不像位置参数那么简单,因为它们以键值对的形式出现。即使您以这种方式传递值,您也需要键来获取它们。只要它们不是唯一的环境变量,在没有充分考虑的情况下我不会假设它们。但这个方法是可行的。您所需要做的就是在感兴趣的各方之间共享密钥。键本身可以基于模式。以下是如何完成此操作的示例。

    有两个脚本 -p.bashc.bashp代表父母,而c代表孩子。它们可以被中介分开,只要中介不会删除通过环境传输的值。为简单起见,这两个脚本在p.bash调用中具有直接连接c.bash

    这是p.bash

    #!/bin/bash
    shift #consume the first argument
    #parse and export the other arguments
    prefix=abcdef_
    i=0
    for a in "$@"; do
        export "$prefix""$i"="$a"
        ((i++))
    done
    ./c.bash
    

    这是c.bash

    #!/bin/bash
    #consume the env arguments
    prefix=abcdef_
    env | grep ^"$prefix"
    

    这是执行过程:

    $ ./p.bash arg "1 2" "3 4" "5 6"
    abcdef_0=1 2
    abcdef_1=3 4
    abcdef_2=5 6
    

    我将解释两行,每个脚本各一行。

    第一个是发电机,

     export "$prefix""$i"="$a"
    

    exportabcdef_0使用、等形式的变量填充环境abcdef_1。现在子进程可以在其环境中找到它们。 (只要它们没有被某些中间人重置。)

    env | grep ^"$prefix"孩子就是消费者。env列出环境变量,并grep过滤掉与负责相关传输的前缀无关的所有行。一旦您了解了这里发生的情况,您应该能够访问传输的变量并在后代进程中使用它们。

相关内容