Bashで起こりうるバグ?:foo(){echo“ $ {var [0]}”; }; var =(bar baz)foo


22

OS:Ubuntu 16.04.3

シェル:Bash 4.3.48


のように変数の内容を一時的に変更することが可能であることを知っています。var=value commandおそらくこれIFS= read -r varが最も顕著なケースです。

そして、グレッグのウィキのおかげで、私も理解しています:

# Why this
foo() { echo "$var"; }
var=value foo

# And this does work
var=value; echo "$var"

# But this doesn't
var=value echo "$var"

私の理解を逃れるのはこれです:

$ foo() { echo "${var[0]}"; }
$ var=(bar baz) foo
(bar baz)

私の知る限り(そして前の例のロジックに従って)、印刷すべきであり、ではbarありません(bar baz)

これは私だけに起こりますか?これは意図された動作ですか、何か不足していますか?それともバグですか?


3
おそらく、bashは環境変数として配列をサポートしていないという事実と関係があるのでしょうか?
Jesse_b

3
@Jesse_bたぶん。私が走るときにはexport var=(foo bar); echo "${var[0]}"プリントしますがfoo、プリントしませんが(foo bar)
nxnev

1
奇数、それも私のために働いた。そして、exportそれを使用して示します:declare -ax var=([0]="foo" [1]="bar")
Jesse_b

3
環境に配列を含めることはできません。たとえば、export i_am_array=(foo bar); /usr/bin/env | grep i_am_arrayここには出力がありません。
デロバート

3
また、:foo() { declare -p var; } ; var=(bar baz) foo与えるdeclare -x var="(bar baz)"その文字列としてではなく、アレイを処置されている確認
derobert

回答:


19

一般的な呼び出し:

var=value cmd

どこcmd機能はポータブルではありません。

bash、それはスカラー変数(およびx=(...)配列として解析されるがスカラーとして割り当てられる)でのみ機能し、それを行うとスコーピングにいくつかの問題があります、ksh93そしてyash、で機能しますが、変数定義はその後も残ります。を使用mkshすると、構文エラーが発生します。Bourneシェルでは、スカラー変数であってもまったく機能しませんでした。

また、スカラー変数であっても、関数内で変数がエクスポートされる(つまり、実行されるコマンドに渡される)かどうかはシェルごとに異なることに注意してください(bash、yash、mksh、zshにありますが、kshにはありません)。灰)。

それはあなたが期待する方法でのみ機能しますzshzsh配列インデックスは1から始まることに注意してください。

bash-4.4$ zsh
$ a=(before value)
$ f() echo $a[1]
$ a=(temp value) f
temp
$ echo $a[1]
before

12

これは単なるバグではなく、実装される予定のない機能のようです。2014年のこのメーリングリストの投稿には、作成者による次のようなものがあります。

幸いなことに、bash 4.3(パッチレベル25)では、-DARRAY_EXPORTだけでは配列変数のインポート/エクスポートを取得できません。コードはコンパイルされず、修正してもリンクしません。修正すると、次の問題が発生します。

これだけのために経験するのは大変なことです。アレイのエクスポートを有効にする予定はありません。

Bashの最新のgitリポジトリから取得すると、次のようになりvariables.cます。

  #  if ARRAY_EXPORT
        /* Array variables may not yet be exported. */

そこにあるものは何でも完全ではないことを示唆しています。


5
ここでは、これは関数のためのものであるため、execve()システムコールが関与していないので、何をエクスポートしても問題はありません。zsh一時的に配列がそのように設定された関数の呼び出しをサポートするシェルを参照してください。
ステファンシャゼル

@StéphaneChazelasしかし、環境は(新しい変数を追加することによって)変化し、関数が完了した後に元に戻ります(この場合についてです:)my_var=one func_bar。それexportが環境に追加されていると言えますか?したがって、エクスポートはここで、内部で使用されますか?私の答えを見て、デモコードを追加しました。
MiniMax

10

以下からman bashのバグセクション(のバージョンはbash4.3です):

バグ

   Array variables may not (yet) be exported.

次のコードは、関数の実行中にのみ一時変数が環境に存在することを示しています。関数が完了すると、一時変数は消えます。

### defining the "bar" function
### it pass all environment variables to the "grep" command
### and the "grep" prints the only "my_var" variable from it
bar() { env | grep my_var=; }

### calls the "bar" function with the temporary 
### variable "my_var" created and assigned.
my_var=one bar

my_var=one         ### The output. The environment contains the "my_var" variable

### checks, does the environment still have the "my_var" variable
### (It doesn't have.)
env | grep my_var=
                   ### The output is empty,
                   ### the environment doesn't contain the "my_var" variable

関連情報:

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.