シュルスクリプトで、コマンドの前に代入を書くとコマンドを実行するときに一時的にシェル変数と環境変数を設定できて便利。
よくある用法
readで空白も読みたいときにIFS=""を指定する場合に
echo "*** WITHOUT IFS=" cal | while read X; do echo "$X" done echo "*** WITH IFS=" cal | while IFS= read X; do echo "$X" done
実行結果
*** WITHOUT IFS= September 2015 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 *** WITH IFS= September 2015 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
てっきりこの代入は一時的だとおもっていたのだが、呼ばれるコマンドがシェル関数かコマンドかで挙動が違うらしい。
ふみやす@シェルまおう(自称ではない)@satoh_fumiyasu
.@koie http://t.co/k6uEPRAK8Y 「31. Assignment statements preceding shell function calls persist in the shell environment after 〜」ですね。へぇ。
2015/07/01 17:52:32
http://tiswww.case.edu/php/chet/bash/POSIX
31. Assignment statements preceding shell function calls persist in the shell environment after the function returns, as if a POSIX special builtin command had been executed.
鯉江@koie
@satoh_fumiyasu なるほど、
2015/07/01 18:25:35
foo() {
X=1
}
X=2 foo
って書いた時に仕様がぶつかってしまうと。。。
試した環境
- FreeBSD /bin/sh
- CentOS /bin/dash
- bash
- bash -o posix
テストスクリプト
f() { echo "$X" /usr/bin/printenv X } g() { X="$X.g1" f X="$X.g2" f } h() { X="$X.h1" g X="$X.h2" g } X=m1 h X="$X.m2" h
sh
m1.h1.g1 m1.h1.g2 m1.h2.g1 m1.h2.g2 .m2.h1.g1 .m2.h1.g2 .m2.h2.g1 .m2.h2.g2
dash
m1.h1.g1 m1.h1.g1.g2 m1.h1.g1.g2.h2.g1 m1.h1.g1.g2.h2.g1.g2 m1.h1.g1.g2.h2.g1.g2.m2.h1.g1 m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2 m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2.h2.g1 m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2.h2.g1.g2
bash
m1.h1.g1 m1.h1.g1 m1.h1.g2 m1.h1.g2 m1.h2.g1 m1.h2.g1 m1.h2.g2 m1.h2.g2 .m2.h1.g1 .m2.h1.g1 .m2.h1.g2 .m2.h1.g2 .m2.h2.g1 .m2.h2.g1 .m2.h2.g2 .m2.h2.g2
bash -o posix
m1.h1.g1 m1.h1.g1 m1.h1.g1.g2 m1.h1.g1.g2 m1.h1.g1.g2.h2.g1 m1.h1.g1.g2.h2.g1 m1.h1.g1.g2.h2.g1.g2 m1.h1.g1.g2.h2.g1.g2 m1.h1.g1.g2.h2.g1.g2.m2.h1.g1 m1.h1.g1.g2.h2.g1.g2.m2.h1.g1 m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2 m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2 m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2.h2.g1 m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2.h2.g1 m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2.h2.g1.g2 m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2.h2.g1.g2
まとめると
Shell | 一時的か? | 環境変数か? |
---|---|---|
fbsd sh | Yes | No |
dash | No | No |
bash | Yes | Yes |
bash -o posix | No | Yes |