免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: icetown
打印 上一主题 下一主题

expect里执行bash脚本中带$9出错 [复制链接]

论坛徽章:
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
11 [报告]
发表于 2012-02-10 17:11 |只看该作者

论坛徽章:
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
12 [报告]
发表于 2012-02-10 17:13 |只看该作者
谨记Don Libes的教导吧,人写了这么一大段

  1. 4.1.1. * At The Beginning Of A Pattern Is Rarely Useful

  2. Patterns match at the earliest possible character in a string. In Chapter 3 (p. 74), I showed how the pattern hi matched the first hi in philosophic. However, in the example above, the subpattern hi matched the second hi. Why the difference?

  3. The difference is that hi was preceded by "*". Since the * is capable of matching anything, the leading * causes the match to start at the beginning of the string. In contrast, the earliest point that the bare hi can match is the first hi. Once that hi has matched, it cannot match anything else—including the second hi.
  4. 4.1.2. * At The End Of A Pattern Can Be Tricky

  5. When a * appears at the right end of a pattern, it matches everything left in the input buffer (assuming the rest of the pattern matches). This is a useful way of clearing out the entire buffer so that the next expect does not return a mishmash of things that were received previously and things that are brand new.

  6. Sometimes it is even useful to say:

  7. expect *


  8. Here the * matches anything. This is like saying, "I don't care what's in the input. Throw it away." This pattern always matches, even if nothing is there. Remember that * matches anything, and the empty string is anything! As a corollary of this behavior, this command always returns immediately. It never waits for new data to arrive. It does not have to since it matches everything.

  9. In the examples demonstrating * so far, each string was entered by a person who pressed return afterwards. This is typical of most programs, because they run in what is called cooked mode. Cooked mode includes the usual line-editing features such as backspace and delete-previous-word. This is provided by the terminal driver, not the program. This simplifies most programs. They see the line only after you have edited it and pressed return.

  10. Unfortunately, output from processes is not nearly so well behaved. When you watch the output of a program such as ftp or telnet (or cat for that matter), it may seem as if lines appear on your screen as atomic units. But this is not guaranteed. For example, in the previous chapter, I showed that when ftp starts up it looks like this:
  11. Code View: Scroll / Show All

  12. % ftp ftp.uu.net
  13. Connected to ftp.uu.net.
  14. 220 ftp.UU.NET FTP server (Version 6.34 Thu Oct 22 14:32:01 EDT 1992) ready.
  15. Name (ftp.uu.net:don):


  16.                                           


  17. Even though the program may have printed "Connected to ftp.uu.net.\n" all at once—perhaps by a single printf in a C program—the UNIX kernel can break this into small chunks, spitting out a few characters eachtime to the terminal. For example, it might print out "Conn" and then"ecte" and then "d to" and so on. Fortunately, computers are so fast that humans do not notice the brief pauses in the middle of output. The reason the system breaks up output like this is that programs usually produce characters faster than the terminal driver can display them. The operating system will obligingly wait for the terminal driver to effectively say, "Okay, I've displayed that last bunch of characters. Send me a couple more." In reality, the system does not just sit there and wait. Since it is running many other programs at the same time, the system switches its attention frequently to other programs. Expect itself is one such "other program" in this sense.

  18. When Expect runs, it will immediately ask for all the characters that a program produced only to find something like "Conn". If told to wait for a string that matches "Name*:", Expect will keep asking the computer if there is any more output, and it will eventually find the output it is looking for.

  19. As I said, humans are slow and do not notice this chunking effect. In contrast, Expect is so fast that it is almost always waiting. Thus, it sees most output come as chunks rather than whole lines. With this in mind, suppose you wanted to find out the version of ftp that a host is using. By looking back at the output, you can see that it is contained in the greeting line that begins "220" and ends with "ready.". Naively, you could wait for that line as:

  20. expect "220*"                     ;# dangerous


  21. If you are lucky, you might get the entire line stored in $expect_out(0,string). You might even get the next line in there as well. But more likely, you will only get a fragment, such as "220 f" or "220 ftp.UU.NE". Since the pattern 220* matches either of these, expect has no reason to wait further and will return. As I stated earlier, expect returns with whatever is the longest string that matches the pattern. The problem here is that the remainder of the line may not have shown up yet!

  22. If you want to get the entire line, you must be more specific. The following pattern works:

  23. "220*ready."


  24. By specifying the text that ends the line, you force expect to wait for the entire line to arrive. The "." is not actually needed just to find the version identifier. You could just make the pattern:

  25. "220*re"


  26. Leaving off the e would be too short. This would allow the pattern to match the r in server rather than ready. It is possible to make the overall pattern even shorter by looking for more unusual patterns. But quite often you trade off readability. There is an art to choosing patterns that are correct, yet not too long but still readable. A good guideline is to give more priority to readability. The pattern matching performed by Expect is very inexpensive.
复制代码

论坛徽章:
0
13 [报告]
发表于 2012-02-10 17:32 |只看该作者
改成下面这样,但是打印还是空的,没有任何输出,怪异。。。

expect -re ".*" {
        set aaa $expect_out(0,string)
        send_user "aaa=$aaa\n"
        send_user buffer=$expect_out(buffer)
        send_user string=$expect_out(0,string)
}

论坛徽章:
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
14 [报告]
发表于 2012-02-11 08:46 |只看该作者
回复 13# icetown

-re ".*"不是和 -gl * 一样的么?


   

论坛徽章:
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
15 [报告]
发表于 2012-02-11 08:54 |只看该作者
本帖最后由 waker 于 2012-02-11 08:55 编辑

如果不能预测输出的结果是什么或是什么模式,基本就不可能用expect了

  1. set timeout 5
  2. expect "\n" {
  3.         set aaa $expect_out(0,string)
  4.         send_user "aaa=$aaa\n"
  5.         send_user "buffer=$expect_out(buffer)"
  6.         send_user "string=$expect_out(0,string)"
  7.         send_user "\n+++++++++++++++++++++\n"
  8.         exp_continue
  9. }
复制代码

论坛徽章:
0
16 [报告]
发表于 2012-02-11 11:14 |只看该作者
回复 1# icetown


    去掉bash

send "startTime=`ls -lrt | tail -1 | awk '{print $9}'` \r"

论坛徽章:
0
17 [报告]
发表于 2012-03-13 18:54 |只看该作者
发现expect里面用2次管道ok,3次管道命令就挂了,即

两次,OK!
expect1.41> ls -lrt | tail -1
-rw-rw-r-- 1 yliu cc_rdr_mxranc     10 Mar 13 14:18 aaa

三次,挂了!
expect1.42> ls -lrt | tail -1 | echo aaa
aaa
child killed: write on pipe with no readers
    while executing
"exec >&@stdout <@stdin /bin/ls -lrt | tail -1 | echo aaa"
    ("uplevel" body line 1)
    invoked from within
"uplevel 1 exec $redir $new [lrange $args 1 end"
    (procedure "unknown" line 72)
    invoked from within
"ls -lrt | tail -1 | echo aaa"
expect1.43> ls -lrt | tail -1 | awk '{print $(9)}'
can't read "(9)": no such variable
    while executing
"ls -lrt | tail -1 | awk '{print $(9)}'"

所以,改变策略,先用两次管道搞出文件名,再用lindex获取$9,搞定。
为啥awk '{print $(9)}'不行,留待后人去搞吧。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP