LoginSignup
1
0

More than 1 year has passed since last update.

bashの変数の展開がいつ行われるのか? あれ、代入済みなのに反映されない?

Posted at

bashの変数の展開がいつ行われるのか? あれ、代入済みなのに反映されない?

bashの変数の展開やコマンドの実行の順番の解釈の理解になれば幸いです。

遭遇した問題

$ TEST_A=abc echo $TEST_A

果たして、これは何が出力されるでしょうか?もともとTEST_Aという変数は未定義だったとします。

答え:

$ TEST_A=abc echo $TEST_A

(何も出力されない)

あれ?abcじゃないの?と数人で混乱していました。

なにが起こっていたか

bashのparserが先に変数TEST_Aを展開するため、TEST_A=abcとは関係なく。何も出力されていませんでした。

そもそもシェルで変数が展開されたあとにコマンドが頭から順番に実行されるため、実質的に

$ TEST_A=abc echo 

をしていたわけですね。したがって

$ TEST_B=hoge
$ TEST_B=abc echo $TEST_B

の場合にはhogeが出力されるわけですが、実質的には

$ TEST_B=hoge
$ TEST_B=abc echo hoge

を実行していたわけです。

確認問題

問題

test.pyを以下の内容で作成します(Python3.6以上)。

import os
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--arg')
args = parser.parse_args()
print(f"{args.arg} {os.environ['TEST_A']}")

このとき、以下を実行するとなにが実行されるでしょうか?

$ TEST_A=foo
$ TEST_A=bar python test.py --arg=$TEST_A

答え

答えを開く
$ TEST_A=bar python test.py $TEST_A
foo bar

解説

arg=$TEST_Aのほうの$TEST_ATEST_A=barが実行される前にこの1行がすべて展開されるのでfooになっています。一方、os.environ['TEST_A']のほうのTEST_Aは、このコマンドが冒頭から実行されるためTEST_A=barが実行されているために、Pythonが実行されるときにはbarに書き換わっています。この1行を展開されるときには当然test.pyの内容は展開されていないためにこのようなことが起きているようです。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0