envを使用してスペースを含む環境変数を設定する

envを使用してスペースを含む環境変数を設定する

子プロセスの環境変数を設定するために使用しようとしていますenv(他のソース(ファイルなど)から読み取る)。デフォルトでは、次のことを試しています。

env VALUE=thisisatest ./somescript.sh

たとえば、次のような場合somescript.shです。

echo $VALUE

これはthisisatest期待どおりに印刷されます。しかし、ファイルから変数をロードしたいと思います。私はこのポイントに達しました:

env $(cat .vars | xargs -d '\n') ./somescript.sh

しかし、変数にスペースが含まれていると問題が発生します(引用符が期待どおりに機能しません)。。たとえば、

env $(echo 'VALUE="this is a test"' | xargs -d '\n') ./somescript.sh

エラーを報告します

env: is: No such file or directory

そして試してみてください:

env $(echo 'VALUE="thisisatest"' | xargs -d '\n') ./somescript.sh

私に予期せぬことを与えるでしょう:

"thisisatest"

env VALUE="thisisatest" ./somescript.sh私は実行が引用符なしで印刷するので、これはうまくいくと思います。

エラーで、私は何らかの理由でenvが引用符が次の値が文字列でなければならないことを意味しないことを理解していないことを理解しています。しかし、引用符を正しく解釈する方法でこれらの変数を挿入する方法はわかりません。

誰もが私がこれを達成する方法についてのアドバイスを提供できますか?

ありがとうございます!

答え1

コマンドの置換には二重引用符を使用する必要があります。それ以外の場合、シェルはコマンド置換の結果に基づいてフィールド分割を実行します。

$ env "$(echo 'VALUE="this is a test"')" ./somescript.sh
"this is a test"

ファイルから読み取るには、envシェルにフィールド分割を実行させる必要がありますが、IFSコマンドが空白のため中断されないように改行文字にのみ設定する必要があります。

$ IFS='
'
$ env $(cat .vars) ./somescript.sh

ファイルから読み取るには、ソース(別名)を使用することをお勧めします。指す)ファイルの場所somescript.sh

#!/bin/bash

. .vars
: The rest of script go here

答え2

これは働きます:

env -S "`cat .vars`" command

まず、ファイル内の変数値を引用する必要があります。

VALUE="This has spaces"

その後、この-Sフラグは変数を解析するために使用されます(引用符を削除)。

env -S "`cat .vars`" command-refers-to-env-vars

もちろん、$VALUEコマンドはシェルによって評価されるため、コマンドに引用できません。以前アクションenv。これを行うには、以下を使用する必要があります。

( . .vars ; echo $VALUE )

括弧はサブシェルを開き、シェルのすべての定義でシェルを汚染しないようにします.vars。ただし、これらの変数はシェルにのみ適用されます。実際にはないため、envプロセスはprocess.ENV.VALUE呼び出しを介してgetenv("VALUE")その項目にアクセスできませんenv -S

2つを組み合わせることができます。

( . .vars ; env -S "`cat .vars`" command-refers-to-envs $VALUE )

答え3

実際にこれを行うより良い方法があり、問題なく複数の変数を宣言できます。

env {'VALUE=thisisatest','FOO=this is a test'} printenv

答え4

私の考えでは、あなたが物事をあまりにも複雑に思うと思います。

$ env FOO='this is a test' printenv | egrep -i foo
FOO=this is a test

ところで、引用符はそうではありません。これ質問。値内で変数を置き換えるには二重引用符を使用し、変数の置換などを防ぐには一重引用符を使用します。

必要に応じてコマンド置換を使用してください。書式文字列を使用します。両方を使用してください。

$ env FOO=$'this\tis a test' printenv | egrep -i foo | cat -t
FOO=this^Iis a test
$ env FOO="$(echo $'this\tis a test')" printenv | egrep -i foo | cat -t
FOO=this^Iis a test

これは、コマンド置換を使用するより良い例かもしれません。アイデアは、いくつかの出力を変換することです。必須コマンド何の理由もなく、必要のないコマンド置換を使用する代わりに変数に追加します。

$ env FOO="$(man man)" printenv | egrep -iA5 foo=
FOO=man(1)                                    man(1)



NAME
   man - format and display the on-line manual pages

関連情報