web-dev-qa-db-ja.com

サブシェルを使用してスペース付きのパラメーターを渡す

サブシェルで生成されたパラメータを渡したい「name_value.sh」というシェルがあります。サブシェルからパラメータを受け取るコマンドがスペースを保持するようにするにはどうすればよいですか?

注:これは私が行っていることの非常に単純化された例です。応答する前に完全に読んでください。

簡単な例は次のとおりです。

./name_value.sh $(echo "no_spaces"; echo "with spaces")

Name_value.shは次のようになります。

#!/bin/bash
echo "Name=$1"
echo "Value=$2"

必要な出力は次のとおりです。

Name=no_spaces
Value=with spaces

これは非常に単純化された例です。私の実際のサブシェルは複雑で、ループして数十の名前と値のペアを出力します。これらはすべて同時に生成され、同時にname_value.shに渡される必要があります。また、呼び出しているシェルファイルを制御することもできません。

引用符でエコーし、「%q」でprintfを使用してみました。また、サブシェルの結果を最初に配列に入れることも検討しましたが、それも機能しません。サブシェルの代わりにテキストが入力されたかのようにサブシェルを解釈するには、親シェルが必要です。

1
Tim

はい。 IFS変数(通常はスペース、タブ、改行を含む)を単なる改行に設定します。そうすれば、スペースとタブはWordの分割に使用されません。これにより、目的の出力が得られます。

IFS=$'\n'
set -o noglob # disable the second effect of leaving that
              # $(...) unquoted.
./name_value.sh $(echo "no_spaces"; echo "with spaces")

ただし、私が行うことは、スクリプトをstdinから読み取ることです。

# name_value.sh
IFS= read -r name
IFS= read -r value
echo "Name=$name"
echo "Value=$value"

その後

( echo no_spaces; echo with spaces ) | ./name_value.sh

このアプローチはより堅牢だと思います。

4
glenn jackman

このコマンドを使用する場合

./name_value.sh $(echo "no_spaces"; echo "with spaces")

Bashは「$()」で「sub-shells」コマンドを実行し、出力文字列を返します。

入力コマンド: ./name_value.sh $(echo "no_spaces"; echo "with space")

処理されたコマンド: ./name_value.shno_spacesとスペース

次のステップは、3つの引数を使用してbashスクリプトを実行することです

最初の引数: no_space

2番目の引数: with

番目の引数:スペース


これは、コマンドを使用してスクリプトを手動で呼び出すのと同じです。

./name_value.sh no_spaces with spaces

問題を解決するには、サブシェル呼び出し「$()」を引用符で囲む必要があります。

これが必要です

./name_value.sh $(echo "no_spaces") "$(echo "with spaces")"

そして、あなたが処理したコマンドは

./name_value.sh no_spaces "with spaces"

そして最後に、あなたはそれを出力します

Name=no_spaces
Value=with spaces
1
CorTheZ