1
privil 2016-10-07 11:24:02 +08:00
第二句你分行再试试 = =
|
3
likeunix OP 书上有道例题是这样的:(请看第 7 行)
1 #!/bin/bash 2 #read-ifd:read fields from a file 3 FILE=/etc/passwd 4 read -p "Enter a user naem >" user_name 5 file_info=$(grep "^$user_name" $FILE) 6 if [[ -n "$file_info" ]];then 7 IFS=":" read user pw uid gid name home shell <<< "$file_info" 8 echo "User is $user" 9 echo "UID is $uid" 10 echo "GID is $gid" 11 echo "Full Name is $name" 12 echo "Home is $home" 13 echo "Shell is $shell" 14 else 15 echo "No such user $user_name" >&2 16 exit 1 17 fi |
4
ooxxcc 2016-10-07 11:43:47 +08:00
大概是 CC=gcc-5.1 make 这种用法?
|
5
lululau 2016-10-07 11:48:51 +08:00 1
这个应该是因为参数会先被展开,你可以试试:
int=10 bash -c 'echo $[int-10]' 或者对比下下面这两行应该就明白了: x=10 perl -le 'print $ARGV[0]' $x x=10 perl -le 'print $ENV{"x"}' |
6
is 2016-10-07 11:50:35 +08:00 3
主要是因为 shell 变量展开的顺序
第二句实际执行的是 int=10 echo $(($int-10)) -> int=10 echo $((100-10)) 而不是直观的 int=10 echo $((10-10)) |
7
ceyes 2016-10-08 01:32:59 +08:00 via iPhone
bash 的语法中可以在命令前设置子进程环境变量,它影响且只影响子进程的环境变量,而对父进程没有影响。
楼主中示例的问题出在, echo 是 bash 的内置命令,我理解他是运行在当前进程空间的,而非子进程。楼主可以试试把 echo 换成一个自己写的脚本让其打印变量看看。 |
8
liuxu 2016-10-08 10:08:53 +08:00 1
int=100
int=10 echo $(($int - 10)) echo $int sh -x 输出: + int=100 + int=10 echo 90 90 + echo 100 100 ----------------------------------------- int=100 int=10 echo $((int=$int - 10)) echo $int sh -x 输出: + int=100 + int=10 echo 90 90 + echo 90 90 ----------------------------------------- int=100 xx=10 echo $((int=$int - 10)) echo $int echo $xx sh -x 输出: + int=100 + xx=10 echo 90 90 + echo 90 90 + echo ------------------------------------------ 这样的话看上去是这个意思: int=100 int=10 echo $(($int - 10)) echo int 等同于: parent=100 child=10 echo $(($parent-10)) echo $parent 输出: + parent=100 + child=10 echo 90 90 + echo 100 100 -------------------------------------------- 下面这行 int=10 echo $(($int - 10)) 其实是开了一个新的子环境,并且子环境可以访问全部父环境变量 因为“允许在一个命令之前立即发生一个或多个变量赋值” 所以先执行 echo 命令,然后做赋值 int=10 其实这个 int 是子环境新建的一个变量,与主环境 int 是两个不同的变量 换成 C 语言( linux 是 C 写的,所以设计思想往 C 靠拢): int num = 100; { printf("%d\n",num-10); int num = 10; } printf("%d\n",num); 输出: 90 100 学过 C 的都应该知道,子作用域新建变量与父作用域变量重名时,子作用域变量会覆盖父作用域变量 当子作用域结束时,子作用域变量被销毁,父作用域变量恢复可见状态,所以出现以上情况。 |
9
likeunix OP @liuxu 谢谢这么耐心的回答;但我觉得还是展开顺序的问题,如果按照你所说的
parent=100 child=10 echo $(($parent-10)) echo $parent 那么 chile=10 永远也影响不了 echo $(($parent-10)),这就和"shell 允许在一个命令之前立即发生一个或多个变量赋值,这些赋值为跟随着的命令更改环境变量"不一致了。比如例题的第 7 行: IFS=":" read user pw uid gid name home shell <<< "$file_info" 明显前一命令影响了后面的命令。 |