当我执行var=blah echo -n $var
时,没有打印任何预期的行为,因为bash
首先使用空字符串展开$var
,然后设置临时环境并放置{{1在它中,最后var=blah
以空字符串作为参数运行。另一方面,当我执行echo
时,会考虑IFS=. read a b <<< "k.l"
的新值。如果变量语句后面没有分号,可以考虑变量吗?
答案 0 :(得分:2)
简单命令中的一个或多个赋值会导致变量在shell中设置为变量。如果它们被导出,它们将被继承到shell执行的任何命令的环境中。
使用实际命令运行的简单命令中的赋值 not 更改shell中的变量,但仅将其设置在正在执行的命令的环境中。 (“简单命令”是通常的命令类型,而不是管道或复合命令。请参阅standard for the definition。)
让我们将几种情况与测试脚本进行比较:
$ cat test.sh
echo "var: $var" # print 'var' from the environment
echo "arg: $1" # print the first command line arg
$ unset var
这里,var
在test.sh
的环境中设置,但shell没有该变量,因此命令行中的那个扩展为空:
$ var=foo sh test.sh "$var"
var: foo
arg:
在这里,var
在shell中设置,因此命令行上的那个被展开,但它在test.sh
的环境中设置 :
$ var=foo; sh test.sh "$var"
var:
arg: foo
如果我们将其导出,它也会进入环境:
$ export var; sh test.sh "$var"
var: foo
arg: foo
从概念上讲,您可以将read
视为与其他任何程序一样的程序,因此在同一命令行上设置的IFS
会继承它,并影响read
的工作方式。与上面的var
类似。
虽然IFS
和read
略有例外,因为Bash不会从环境中继承IFS
(dash
确实如此),但重置它,{{1默认情况下不会导出,但IFS
仍会导致IFS=.; read a
使用更改的read
。当然IFS
是内置的,因此它可以看到shell的变量,而不仅仅是导出的变量。我想不出任何其他类似的shell内置使用read
,所以我无法比较。
答案 1 :(得分:0)
read
总是读取一行输入,无论给出多少参数;读取行后,read
本身在其环境中使用IFS
的值将字符串拆分为足够的单词,以填充由其位置参数命名的变量。