shell变量在函数间修改问题

eoollo 2011-08-17 12:02:55
#!/bin/bash
RootPath=.

function aaa () {
a=123
b=456
echo In aaa a:$a b:$b
}

function bbb () {
int=1
find $RootPath | sed '/svn/d' > file
cat file | while [ $int -gt 0 ]
do
echo $line | grep ".cpp$"
(( a=$a+123 ))
(( b=$b+456 ))
(( int=$int-1 ))
echo In bbb a:$a b:$b
done < file
}

aaa
bbb
echo OUT a: $a b: $b

输出为:
In aaa a:123 b:456
In bbb a:246 b:912
OUT a: 123 b: 456

因为管道问题,输出的第二行和第三行不一样
请问我怎么才能让第二行和第三行输出相同,谢谢

我的OS是ubuntu 11.04

谢谢
...全文
242 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
eoollo 2011-09-01
  • 打赏
  • 举报
回复
不胜感激~~
努力多学点,争取不辜负你的回复~~


[Quote=引用 19 楼 joan8363 的回复:]

如果脚本想深入,看书没太大用,从书中先把基础打牢,脚本方面我只看过一本orelly的‘学习bash’,但里面没有命令的用法,对理解shell还是很有用的

其他高级用法都是日常积累的,awk的google一下高级用法(例如数组等),sed的看一下sed1line,(重点在模式空间和交换空间),find,sort,uniq,paste等命令man一下都清楚了

像一些awk,sed一类的书……
[/Quote]
joan8363 2011-09-01
  • 打赏
  • 举报
回复
如果脚本想深入,看书没太大用,从书中先把基础打牢,脚本方面我只看过一本orelly的‘学习bash’,但里面没有命令的用法,对理解shell还是很有用的

其他高级用法都是日常积累的,awk的google一下高级用法(例如数组等),sed的看一下sed1line,(重点在模式空间和交换空间),find,sort,uniq,paste等命令man一下都清楚了

像一些awk,sed一类的书,国内的都只有简单用法,深入一点的都没有
eoollo 2011-09-01
  • 打赏
  • 举报
回复
我手上有本shell脚本书,但是上面都只有一些简单的用法,函数基本没有,因为shell在工作中都是简单的用下,一直shell也没什么进步,实在惭愧。不知道有没有好点的书推荐下,或好的文章。

不胜感激~


[Quote=引用 17 楼 joan8363 的回复:]

如果以文件命名排序,可以在awk里加asorti函数解决

如果以文件个数排序一个命令比较麻烦,直接加个管道吧 | sort -nk2
[/Quote]
joan8363 2011-08-30
  • 打赏
  • 举报
回复
如果以文件命名排序,可以在awk里加asorti函数解决

如果以文件个数排序一个命令比较麻烦,直接加个管道吧 | sort -nk2
eoollo 2011-08-30
  • 打赏
  • 举报
回复
十分感谢,这个很好用

不知道能不能把输出按大小排排序

再次感谢

[Quote=引用 14 楼 joan8363 的回复:]

ls -lR | awk 'NF>=8&&$NF~/\./{gsub(/.*\./,"",$NF);a[$NF]+=$5}END{for(i in a)print i,a[i]}'

那就用gsub试试
[/Quote]
modicum_lf 2011-08-21
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 joan8363 的回复:]
cat file | while [ $int -gt 0 ]
do
echo $line | grep ".cpp$"
(( a=$a+123 ))
(( b=$b+456 ))
(( int=$int-1 ))
echo In bbb a:$a b:$b
done < file

很明显,变量的改变是在子进程中,不会影响到父进程,如果想要改变变量,……
[/Quote]

++

eoollo 2011-08-19
  • 打赏
  • 举报
回复
谢谢先
你的写法就是给我很深的印象,我只能写写简单的函数,对shell了解不多。
但是不知道你用的是什么版本的shell,在我机器上gensub是没有定义的。我的:GNU bash, version 4.2.8(1)-release (i686-pc-linux-gnu)
我的man中是没有gensub的

十分感谢

[Quote=引用 12 楼 joan8363 的回复:]

方法也很多,看你想输出什么

这个是统计有后缀的大小,包括目录,gensub和gsub不同man awk看看吧,印象深

ls -lR | awk 'NF>=8&&$NF~/\./{a[gensub(/(.*)\.(.*)/,"\\2",1,$NF)]+=$5}END{for(i in a)print i,a[i]}'


顺便看看我10楼写的方法,用你的方式应该也……
[/Quote]
joan8363 2011-08-19
  • 打赏
  • 举报
回复
ls -lR | awk 'NF>=8&&$NF~/\./{gsub(/.*\./,"",$NF);a[$NF]+=$5}END{for(i in a)print i,a[i]}'

那就用gsub试试
joan8363 2011-08-18
  • 打赏
  • 举报
回复
方法也很多,看你想输出什么

这个是统计有后缀的大小,包括目录,gensub和gsub不同man awk看看吧,印象深

ls -lR | awk 'NF>=8&&$NF~/\./{a[gensub(/(.*)\.(.*)/,"\\2",1,$NF)]+=$5}END{for(i in a)print i,a[i]}'


顺便看看我10楼写的方法,用你的方式应该也可以,这样可以不fork子进程
eoollo 2011-08-18
  • 打赏
  • 举报
回复
在我机器上没跑过,“gensub”是“gsub”吗?

我可能和你考虑的不太一样
我要取的是当前目录下的所有文件:当前目录下可能有文件,也可能有目录,或都有,有几级目录同样不知道
统计所有文件的类型(依据后缀,当然也可能没有后缀:后缀的类型也不知道)和各种类型所总共的大小。

谢谢你的回复

[Quote=引用 8 楼 joan8363 的回复:]

看上去这个问题可以一行搞定的,但描述的还是让我不太懂,猜一下

du *.* | awk '{a[gensub(/(.*)\.(.*)/,"\\2",$2)]+=$1}END{for(i in a)print i,a[i]}'
[/Quote]
joan8363 2011-08-18
  • 打赏
  • 举报
回复
while read line
do
if [ -f $line ];then
if echo $line | grep "\.cpp$" > /dev/null 2>&1; then
size=`ls -al $line | awk '{print $5}'`
.
.
fi
fi
done < <(find | sed '/svn/d')
试一下, 两个<中间有空格,记得脚本开头用bash,即#!/bin/bash
eoollo 2011-08-18
  • 打赏
  • 举报
回复
我是这样写的:

find | sed '/svn/d' | while read line
do
if [ -f $line ];then
if echo $line | grep "\.cpp$" > /dev/null 2>&1; then
size=`ls -al $line | awk '{print $5}'`
.
.
fi
fi
done

cat file 是为了方便

[Quote=引用 7 楼 louyong0571 的回复:]

引用 6 楼 eoollo 的回复:
cat file 取出 file 中的内容
应该不是这个原因
谢谢了~



引用 4 楼 louyong0571 的回复:

cat file | while [ $int -gt 0 ]
cat file是起什么作用?貌似就是它引起的

我知道cat file 取出 file 中的内容
我是说你放在这里有什么作用。我感觉是这个c……
[/Quote]
joan8363 2011-08-17
  • 打赏
  • 举报
回复
cat file | while [ $int -gt 0 ]
do
echo $line | grep ".cpp$"
(( a=$a+123 ))
(( b=$b+456 ))
(( int=$int-1 ))
echo In bbb a:$a b:$b
done < file

很明显,变量的改变是在子进程中,不会影响到父进程,如果想要改变变量,不要在子进程中改变
joan8363 2011-08-17
  • 打赏
  • 举报
回复
看上去这个问题可以一行搞定的,但描述的还是让我不太懂,猜一下

du *.* | awk '{a[gensub(/(.*)\.(.*)/,"\\2",$2)]+=$1}END{for(i in a)print i,a[i]}'
louyong0571 2011-08-17
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 eoollo 的回复:]
cat file 取出 file 中的内容
应该不是这个原因
谢谢了~



引用 4 楼 louyong0571 的回复:

cat file | while [ $int -gt 0 ]
cat file是起什么作用?貌似就是它引起的
[/Quote]
我知道cat file 取出 file 中的内容
我是说你放在这里有什么作用。我感觉是这个cat file造成了子shell的产生,
你试试看不用这个cat file
eoollo 2011-08-17
  • 打赏
  • 举报
回复
cat file 取出 file 中的内容
应该不是这个原因
谢谢了~


[Quote=引用 4 楼 louyong0571 的回复:]

cat file | while [ $int -gt 0 ]
cat file是起什么作用?貌似就是它引起的
[/Quote]
eoollo 2011-08-17
  • 打赏
  • 举报
回复
统计目录 $RootPath 下的不同文件(依据后缀)的大小。

有什么好的思路,分享下

谢谢

[Quote=引用 3 楼 joan8363 的回复:]

不太明白是什么需求,必须要在循环里给变量赋值?
[/Quote]
louyong0571 2011-08-17
  • 打赏
  • 举报
回复
cat file | while [ $int -gt 0 ]
cat file是起什么作用?貌似就是它引起的
joan8363 2011-08-17
  • 打赏
  • 举报
回复
不太明白是什么需求,必须要在循环里给变量赋值?
eoollo 2011-08-17
  • 打赏
  • 举报
回复
谢谢你的回复~

这是我简化的脚本

因为有些值是要在 “ echo $line | grep ".cpp$" ”后得到,要先定位到文件,然后才能取到文件的信息。在这种情况下,我该怎么做才能把我取得文件信息传出去哪?

或在有什么更好的思路,不用产生子进程?

谢谢

23,116

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧