免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 6130 | 回复: 25
打印 上一主题 下一主题

请帮忙看看变量为什么没有被赋值 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-11-19 19:36 |只看该作者 |倒序浏览

  1. $ cat > a.sh
  2. for x in 1 2 3
  3. do
  4. y=$x
  5. done   
  6. echo $y

  7. $cat > b.sh
  8. while read x
  9. do
  10. y=$x
  11. done < <(ls)
  12. echo $y

  13. cat > c.sh
  14. ls | while read x
  15. do
  16. y=$x
  17. done
  18. echo $y
复制代码


$ bash a.sh | cat -A
3$
$ bash b.sh | cat -A
c.sh$
$ bash c.sh | cat -A
$


为什么使用第三中写法变量y的值是空的呢?

论坛徽章:
0
2 [报告]
发表于 2006-11-19 20:36 |只看该作者
刚才错了...
重新写个脚本看了一下...
ext="haha"

ls | while read x
do
echo $ext
echo x: $x
y=$x
echo y: $y
done
echo "end: $x y"

最后x, y都没有了... 又不是sub shell...不然ext就不应该能访问...

[ 本帖最后由 Edengundam 于 2006-11-19 20:48 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2006-11-19 21:13 |只看该作者

  1. [n7css@monitor n7css]$ ls > result
  2. [n7css@monitor n7css]$ while read x ;do
  3. > echo $x
  4. > done < result
  5. alert_mail.sh
  6. auto_telnet
  7. bash-3.0-31.i386.rpm
  8. get_service_statu.sh
  9. mrtg_config.tar.gz
  10. mrtg_data.tar.gz
  11. next.JPG
  12. prev.JPG
  13. result
  14. [n7css@monitor n7css]$
复制代码

论坛徽章:
0
4 [报告]
发表于 2006-11-19 21:13 |只看该作者

  1. #!/bin/sh

  2. echo "---------------------start------------------------------"
  3. echo "first pid is :$$"
  4. ps
  5. echo "----------------------end-------------------------------"

  6. echo '1
  7. 2' > tmp.input


  8. echo "---------------------start------------------------------"
  9. while read test
  10. do
  11.     echo "pid: $$"
  12.     test1=$test
  13.     set | grep '^test1'
  14.     ps
  15. done < tmp.input

  16. echo "out of while: "`set | grep '^test1'`

  17. echo "----------------------end-------------------------------"

  18. echo "---------------------start------------------------------"
  19. cat tmp.input | while read test
  20. do
  21.     echo "pid: $$"
  22.     test2=$test
  23.     set | grep '^test2'
  24.     ps
  25. done

  26. echo "out of while: "`set | grep '^test2'`

  27. echo "----------------------end-------------------------------"

  28. rm tmp.input
复制代码



结果

  1. Administrator@EDENSXY ~
  2. $ test.sh
  3. ---------------------start------------------------------
  4. first pid is :872
  5.       PID    PPID    PGID     WINPID  TTY  UID    STIME COMMAND
  6.      3648       1    3648       3648  con  500 22:49:28 /usr/bin/bash
  7.       872    3648     872       3432  con  500 22:56:41 /usr/bin/sh
  8.      3076     872     872       3080  con  500 22:56:41 /usr/bin/ps
  9. ----------------------end-------------------------------
  10. ---------------------start------------------------------
  11. pid: 872
  12. test1=1
  13.       PID    PPID    PGID     WINPID  TTY  UID    STIME COMMAND
  14.      3648       1    3648       3648  con  500 22:49:28 /usr/bin/bash
  15.       872    3648     872       3432  con  500 22:56:41 /usr/bin/sh
  16.      4052     872     872       1876  con  500 22:56:42 /usr/bin/ps
  17. pid: 872
  18. test1=2
  19.       PID    PPID    PGID     WINPID  TTY  UID    STIME COMMAND
  20.      3648       1    3648       3648  con  500 22:49:28 /usr/bin/bash
  21.       872    3648     872       3432  con  500 22:56:41 /usr/bin/sh
  22.      2720     872     872       3068  con  500 22:56:42 /usr/bin/ps
  23. out of while: test1=2
  24. ----------------------end-------------------------------
  25. ---------------------start------------------------------
  26. pid: 872
  27. test2=1
  28.       PID    PPID    PGID     WINPID  TTY  UID    STIME COMMAND
  29.      3648       1    3648       3648  con  500 22:49:28 /usr/bin/bash
  30.       872    3648     872       3432  con  500 22:56:41 /usr/bin/sh
  31.      3448     872     872       3448  con  500 22:56:42 /usr/bin/sh
  32.      2256    3448     872       3716  con  500 22:56:42 /usr/bin/ps
  33. pid: 872
  34. test2=2
  35.       PID    PPID    PGID     WINPID  TTY  UID    STIME COMMAND
  36.      3648       1    3648       3648  con  500 22:49:28 /usr/bin/bash
  37.       872    3648     872       3432  con  500 22:56:41 /usr/bin/sh
  38.      3448     872     872       3448  con  500 22:56:42 /usr/bin/sh
  39.      2556    3448     872       3976  con  500 22:56:42 /usr/bin/ps
  40. out of while:
  41. ----------------------end-------------------------------

复制代码


能看出, 第一个while和第二个while之间只有一个区别就是一个用重定向, 一个用管道.
管道定义是将两边的命令分别开sub shell来运行...可是这里while是在运行这个脚本的shell中运行的.
发现第二个while中的test2在退出后居然从set中消失了...

修改了下脚本, 每次while还用ps打印下当前进程列表...多了一个sh, 这个结果我在msys下和ubuntu下都测试了, ubuntu下面更准确的告诉使用管道的while当时打开了两个test.sh, 我一直看不到cat...我非常奇怪>_<



仔细观察, 观察他们的派生关系: 使用重定向的while
872    3648     872       3432  con  500 22:56:41 /usr/bin/sh
2720     872     872       3068  con  500 22:56:42 /usr/bin/ps

ps的父进程是一开始运行脚本的sh!!!!
但是使用管道的while:
      872    3648     872       3432  con  500 22:56:41 /usr/bin/sh
     3448     872     872       3448  con  500 22:56:42 /usr/bin/sh
     2556    3448     872       3976  con  500 22:56:42 /usr/bin/ps
ps的父进程居然变成了3448...如果while是子shell那么他凭什么访问父shell没有export的变量?

问题更加扑朔迷离了...除了...

看来只能等待高人了...

[ 本帖最后由 Edengundam 于 2006-11-19 23:45 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2006-11-19 23:21 |只看该作者
给您个资料看,这里讲得很明白~~
http://www.unix.org.ua/orelly/unix/ksh/ch07_02.htm

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
6 [报告]
发表于 2006-11-19 23:22 |只看该作者
进程和子进程的问题,b.sh用到了进程替换,也就师说,实际上并没有产生子进程,而c.sh由于用到了管道,ls|while...,明显产生了一个子进程,当管道动作结束后,子进程的东西无法传递出来,因为子进程消失了.

论坛徽章:
0
7 [报告]
发表于 2006-11-19 23:39 |只看该作者
原帖由 寂寞烈火 于 2006-11-19 23:22 发表
进程和子进程的问题,b.sh用到了进程替换,也就师说,实际上并没有产生子进程,而c.sh由于用到了管道,ls|while...,明显产生了一个子进程,当管道动作结束后,子进程的东西无法传递出来,因为子进程消失了.



这里就一个问题: 不经过export的环境变量是不能被子shell访问的!!!

但是使用管道的while却能够访问环境变量~~~~~~~~~~

除非...这个子shell和普通不一样, 才会导致看到2个sh, 而又存在隐含的环境变量export吧~~~~

所以我困惑于...开子shell就不应该可以访问父shell的未经过export的变量吧~~~这个子shell违背了正常子shell的特征吧~~~

[ 本帖最后由 Edengundam 于 2006-11-19 23:42 编辑 ]

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
8 [报告]
发表于 2006-11-19 23:52 |只看该作者
原帖由 Edengundam 于 2006-11-19 23:39 发表



这里就一个问题: 不经过export的环境变量是不能被子shell访问的!!!

但是使用管道的while却能够访问环境变量~~~~~~~~~~

除非...这个子shell和普通不一样, 才会导致看到2个sh, 而又存在隐含的环境变量e ...

ABS里进程替换章节
http://www.linuxsir.org/main/doc/abs/abs3.7cnhtm/process-sub.html
其中最典型的例子,和楼主的两脚本很类似

论坛徽章:
0
9 [报告]
发表于 2006-11-20 09:02 |只看该作者
原帖由 寂寞烈火 于 2006-11-19 23:52 发表

ABS里进程替换章节
http://www.linuxsir.org/main/doc/abs/abs3.7cnhtm/process-sub.html
其中最典型的例子,和楼主的两脚本很类似



谢谢, 我发现我脚本可能存在设计问题, 所以引用到了那个没有export的变量, 我晚点再重新写一次看看.

但是还有个问题: 在同一个while体内的 ps 和 echo $$ 为什么ps 的PPID不是echo $$出来的PID呢...这里感觉上echo $$是开始的shell, ps确被子shell启动的...

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
10 [报告]
发表于 2006-11-20 09:26 |只看该作者
9F:

http://bbs.chinaunix.net/viewthread.php?tid=733138

对你的问题有帮助么?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP