Bash - 引数は出力時にbashを解析しないでください。

Bash - 引数は出力時にbashを解析しないでください。

2つのシェルスクリプトがあります。最初は2番目をトリガーし、いくつかのパラメータを追加します。 2番目のスクリプトはコマンドを呼び出し、最初のスクリプトのパラメータをコマンドの引数として追加します。

最初のものは次のとおりです。

#!/usr/bin/env bash

ADDITIONAL_ARGUMENTS='--set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}"'

SUPER_PARAMS=${ADDITIONAL_ARGUMENTS} my_second_script.sh

次に、2番目のスクリプトは次のことを行います。

#!/usr/bin/env bash

randomBinary --some-hardcoded-parameters \
             "${SUPER_PARAMS}"

私が期待する結果は次のとおりです。

randomBinary --some-hardcoded-parameters --set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}"

しかし、代わりに呼び出しは次のようになります。

randomBinary --some-hardcoded-parameters '--set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}"'

パラメータを正しく引用しようと2日間試しましたが、結果はありません。

答え1

複数のパラメータを保存するには、スカラー変数の代わりに配列を使用します。

additional_arguments=(
  --set
  'args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}'
)
randomBinary --some-hardcoded-parameters "${additional_arguments[@]}"

環境変数はNULではなくバイトの文字列なので、配列定義を環境を介して他のコマンドに渡すには、いくつかのエンコーディングが必要です。

kshbashまたは以下zshyash使用できます。

ARRAY_DEFINITION="$(typeset -p additional_arguments)" my_second_script.sh

配列定義を呼び出しスクリプトの環境変数にエクスポートします。

そしてeval "$ARRAY_DEFINITION"呼び出しスクリプトで輸入配列定義。

コードが生成されたロケールと同じロケールで同じシェルを使用してコードを評価することが重要です。

また、配列定義が関数内で評価される場合、配列はその関数に対してローカルになります。

一部のシェルは配列のエクスポート(内部で独自のエンコーディングを使用)を優先またはrc許可します。esfish

ここでは、情報を呼び出されたスクリプトにパラメータとして渡すのが配列であるため、簡単になります。

呼び出しスクリプトから:

my_second_script.sh "${additional_arguments[@]}"

呼び出しスクリプトから:

randomBinary --some-hardcoded-parameters "$@"

または、呼び出し側のシェル変数を共有するために呼び出されたスクリプトを呼び出すと、.実行中にそのデータを渡すために環境を使用する必要はありません。

答え2

ここでは、

randomBinary --some-hardcoded-parameters "${SUPER_PARAMS}"

SUPER_PARAMS含め--set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}"て引用されたので、そのまま渡されます。引用符がない場合は、スペースに基づいて5つの文字列--set、、、、"args={/bin/bash,-c,cd/var/www分割され、これらの文字列は引数として渡されます。&&sudo -u www-data bash scripts/system/update.sh}"

変数内の引用符も解釈されたいと思います。これを行うには、別のシェル構文解析レイヤーを追加するか、またはを介してevalそのエントリを実行する必要があります。bash -c '...'

テストスクリプトは次のとおりです。

$ cat test.sh
#!/bin/bash    
ARGS='--set "args={this, that && that}"'
./args.sh $ARGS
eval "./args.sh $ARGS"

印刷:

<!-- language: lang-none -->
$ bash test.sh
5 args: <--set> <"args={this,> <that> <&&> <that}"> 
2 args: <--set> <args={this, that && that}> 

args.shスクリプトによって印刷される数字はさまざまなパラメータの数であり、パラメータ自体はに印刷されます<...>。)

たとえば、evalコマンド置換を実行するため、ランダムなコード実行が開きます。通常、自分の主張を次のように説明するのが最善です。シェル配列代わりに、ここではあるスクリプトから別のスクリプトに渡すので、うまく動作しません。 「変数にコマンドを保存する方法」を参照してください。存在するスペース処理へのこの回答

返品Bashガイドの噴射set -xまた、シェルが実際に実行したコマンドを確認することもできます。

関連情報