web-dev-qa-db-ja.com

孫プロセスで使用する引数を渡す

引数と3つのプロセスのリストがあります。

bash_script -> child -> grandchild

議論のリストは孫を対象としています。 3つのプロセスすべてを変更できます。おじいさんのスクリプトは、それ自体について1つの引数を取得します。

以下は孫に残りの引数を渡す適切な方法ですか?

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

export MY_ARGS="$@"

私は、孫を呼び出すコマンドの一部として、子プロセスで、後でenv変数を「展開」します。

grandchild --foo "$MY_ARGS"  # append $MY_ARGS as arguments to foo
5
Alexander Mills

スクリプトでは、配列を文字列に降格しないでください。環境変数とその値は単純なkey=valueペア。ここで、keyvalueは両方とも文字列です。位置パラメータを(連結によって)単純な文字列に降格すると、それらの間の分離を保持することが困難になり、それらを使用したいときに引用を正しく行うことが難しくなります。

代わりに、コマンドラインで次のスクリプトに渡す定位置パラメーター(コマンドライン引数)を渡します。

#!/bin/bash

first_arg=$1
shift

# later ...

./my_other_script "$@"

他のスクリプトでは:

#!/bin/bash

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

編集:それはあなたがbashで配列をエクスポートできないようです。配列などをセットアップする関数をエクスポートする必要がある場合があります。

配列を使用する必要があります。そうしないと、スペースを含む引数が複数の単語に展開されます。

export MY_ARGS=("$@")


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

なぜ人々が質問に困惑しているのかはわかりませんが、質問が混乱しているかもしれません。これが私にとってうまくいくようです:

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

次に、単にMY_ARGSを次のように使用します。

foo --bar $MY_ARGS

note @Kusalanandaが指摘しているように:元の引数に空白が含まれている場合、これはfailになります。その場合、env変数の代わりに$@を使用して子プロセスに引数を渡すのが最善です。

2
Alexander Mills

一般的な答えはこれです。以下を使用して引数を渡すことができます:

  • コマンドライン定位置パラメーター
  • 環境変数
  • oSで利用可能なIPC(プロセス間通信))

最初の2つだけに焦点を当てるには、

  • 位置パラメータは最も自然な方法です。これには、現在定義されているすべての定位置パラメーターを表す"$@"の編集および送信が含まれます。これは、プロセス階層のすべての段階で実行する必要があります。
  • 環境変数は、キーと値のペアの形式で提供されるため、定位置パラメーターほど単純ではありません。この方法で値を渡す場合でも、それらを取得するにはキーが必要です。それらが唯一の環境変数でない限り、私は十分な考慮なしに仮定しません。しかし、この方法は実行可能です。関係者間で鍵を共有するだけです。キー自体はパターンに基づくことができます。これを行う方法の例を次に示します。

    p.bashc.bashの2つのスクリプトがあります。 pは親を表し、cは子です。それらは、環境を介して送信された値を削除しない限り、仲介者によって分離できます。簡単にするために、これらの2つのスクリプトは、p.bashc.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
    

    各スクリプトからの2行を説明します。

    最初はジェネレーターです

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

    exportは、abcdef_0abcdef_1などの形式の変数を環境に取り込みます。これで、子プロセスが環境内でそれらを見つけることができます。 (仲介者によって解除されない限り)。

    子供のenv | grep ^"$prefix"は消費者です。 envは環境変数をリストし、grepは問題の送信を担当するプレフィックスに関連付けられていないすべての行をフィルターで除外します。ここで何が行われているのかを理解したら、送信された変数にアクセスして、子孫プロセス内でそれらを利用できるはずです。

2
user147505