有关shell中变量的问题

sh/bash/dash/ksh/zsh等Shell脚本
回复
chengmoYS
帖子: 125
注册时间: 2007-10-22 22:40

有关shell中变量的问题

#1

帖子 chengmoYS » 2011-07-25 15:54

写了一个小脚本,为什么sum的值最后还是0呀。
使用sh -x a.sh发现sum在循环中其实一直有变化,感觉跟c里那个什么传参相似。

这里有什么解决方法不。

[root@localhost Desktop]# cat a.sh
#!/bin/sh

sum=0

sed '/root/d' /etc/passwd | awk -F\: '{print $3}' | while read i
do
sum=`expr $sum + $i`
done

echo $sum
[root@localhost Desktop]# sh a.sh
0
Gooney
帖子: 8
注册时间: 2011-07-25 11:36

Re: 有关shell中变量的问题

#2

帖子 Gooney » 2011-07-25 16:22

sum=`expr $sum + $i | bc`
chengmoYS
帖子: 125
注册时间: 2007-10-22 22:40

Re: 有关shell中变量的问题

#3

帖子 chengmoYS » 2011-07-25 16:34

Gooney 写了:sum=`expr $sum + $i | bc`
expr $sum + $i跟expr $sum + $i | bc没区别。
你没看清楚我的问题。谢谢。
Gooney
帖子: 8
注册时间: 2011-07-25 11:36

Re: 有关shell中变量的问题

#4

帖子 Gooney » 2011-07-25 17:51

chengmoYS 写了:
Gooney 写了:sum=`expr $sum + $i | bc`
expr $sum + $i跟expr $sum + $i | bc没区别。
你没看清楚我的问题。谢谢。
sorry,没看清楚。
我试了一下,确实是楼主所说那样,很困惑。
搜索到这个:
http://bbs.chinaunix.net/thread-1727231-2-1.html

看12楼那位的说法,觉得应该有道理。
这个是bash和ksh之间的区别。
bash中需要用 while read line; do ... done <input_file.
而ksh中,直接 cat xxx | while read line; do ... done. 就可以了

另外,ksh 中用起来很方便的地方还有, echo "1 2 3 4" | read a b c d; echo "$a $b $c $d"
而bash就不行了。
Gooney
帖子: 8
注册时间: 2011-07-25 11:36

Re: 有关shell中变量的问题

#5

帖子 Gooney » 2011-07-25 18:02

chengmoYS 写了:
Gooney 写了:sum=`expr $sum + $i | bc`
expr $sum + $i跟expr $sum + $i | bc没区别。
你没看清楚我的问题。谢谢。
抱歉没看清。
这个问题确实有,我搜索了一下,有人说这是bash和ksh的区别,试了试,楼主的脚本在ksh下可以得到你预想的结果。
前面发过一个贴,竟然还说要审核,新人不好混啊
chengmoYS
帖子: 125
注册时间: 2007-10-22 22:40

Re: 有关shell中变量的问题

#6

帖子 chengmoYS » 2011-07-26 9:05

谢谢。楼上的。

也谢谢你们。

呵呵。

新手难混,你也不要走捷径。慢慢来,别急。本来就是学习知识的,急不来的。
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: 有关shell中变量的问题

#7

帖子 fnan » 2011-07-27 18:46

kose1@kose1-desktop:~$ sed '/root/d' /etc/passwd | awk -F\: '{print $3}' |( while read i; do sum=`expr $sum + $i`; done;echo $sum)
68392
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: 有关shell中变量的问题

#8

帖子 fnan » 2011-07-27 18:51

这个是bash和ksh之间的区别。
bash中需要用 while read line; do ... done <input_file.
而ksh中,直接 cat xxx | while read line; do ... done. 就可以了

另外,ksh 中用起来很方便的地方还有, echo "1 2 3 4" | read a b c d; echo "$a $b $c $d"
而bash就不行了。
kose1@kose1-desktop:~$ echo "1 2 3 4" | (read a b c d; echo "$a $b $c $d")
1 2 3 4
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
tinym87
帖子: 5
注册时间: 2011-04-04 13:24

Re: 有关shell中变量的问题

#9

帖子 tinym87 » 2011-07-29 2:42

7楼的回答正解啊!
貌似将while循环这一部分放到()内就没有问题,()内的代码是作为一个独立进程来运行的。

自己弄的一个笨方法也可以用:

代码: 全选

#!/bin/sh

sum=0

sed '/root/d' /etc/passwd | awk -F\: '{print $3}' >>tmp_ex_1.txt
while read i
do
	sum=`expr $sum + $i`
done <tmp_ex_1.txt
rm -f tmp_ex_1.txt

echo $sum
不过还是:

代码: 全选

sed /root/d | awk -F: '{ print $3 }' | (while read i;do sum=`expr $i + $sum`;done;echo $sum)
经典啊。
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: 有关shell中变量的问题

#10

帖子 fnan » 2011-07-29 7:04

这种问题最好用awk:
kose5@kose5-Aspire-4552:~$ awk -F: '{if ($0 !~ /root/) sum+=$3} END{print sum}' /etc/passwd
68165
追踪进程层次可以用$BASH_SUBSHELL 变量。
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: 有关shell中变量的问题

#11

帖子 tusooa » 2011-07-29 11:32

代码: 全选

while read line; ... ; done <<< "$(sed '/root/d' /etc/passwd | awk -F\: '{print $3}')"

代码: 全选

] ls -ld //
回复