|
|
 |
 |
 |
 |
TCL(Tool Command Language) Scripting
|
 |
 |
 |
 |
 |
 |
 |
 |
Expect - failed to write error - 6 lines of code
I'm getting the following error when I run a simple expect script: "write() failed to write anything - will sleep(1) and retry..." It happens when the script exits, so it's not really a problem aside from having to wait for the sleep(1) to occur. It is more of an annoyance in my real script (not shown) because I spawn six telnet sessions, so I have to wait six sleep(1) times. I'm running expect version 5.43.0 on Ubuntu 6.10 on a 2.6.17-11-generic linux kernel. Here's my six line script: #!/usr/bin/expect exp_internal 1 set prompt "foo>" spawn telnet "10.1.1.1" expect -re $prompt send "blah\r" expect -re $prompt {} Any help would be appreciated. # email address not real - no spam
On May 25, 9:18 pm, Skip Gracely <s@hotmail.com> wrote: > "write() failed to write anything - will sleep(1) and retry..." > I'm running expect version 5.43.0 on Ubuntu 6.10 on a > 2.6.17-11-generic linux kernel.
Since you're on linux, use strace -f, you'll see the offending write(). Then you'll be able to investigate why it is blocking or failing in a retryable manner. Post back the strace output if you wish. -Alex
On Sat, 26 May 2007 03:48:00 -0700, Alexandre Ferrieux wrote: > On May 25, 9:18 pm, Skip Gracely <s @hotmail.com> wrote: >> "write() failed to write anything - will sleep(1) and retry..." >> I'm running expect version 5.43.0 on Ubuntu 6.10 on a >> 2.6.17-11-generic linux kernel. > Since you're on linux, use strace -f, you'll see the offending > write(). > Then you'll be able to investigate why it is blocking or failing in a > retryable manner. Post back the strace output if you wish. > -Alex
strace gives: [pid 6834] write(6, "", 0) = 0 where I believe that 6 is the file descriptor of the telnet expect channel. The offending code is line 252 of exp_chan.c ExpOutputProc(...) ... written = write(esPtr->fdout, buf, (size_t) toWrite); if (written == 0) { sleep(1); expDiagLogU("write() failed to write anything - will sleep(1) <snip>; *errorCodePtr = EAGAIN; return -1; }
... This means that some other function is calling the ExpOutputProc function and telling it to output a zero length buffer. My questions are, which function is doing this and why? In any case, I doubt very seriously that it's anything in the simple script I posted, so I'm thinking it's a bug. I know I've seen other posts on various sites asking about the error message, and the dates are from 2005, so I really don't understand why this hasn't been addressed (fixed.)
Skip Gracely wrote: > strace gives: > [pid 6834] write(6, "", 0) = 0 [...] > so I'm thinking it's a bug.
Looks like it; writing zero-length buffers can cause some other problems too (do you want to know about the guts of SysV STREAMS? I hope not!) so it's generally agreed as a Bad Thing. Hence if it is happening, there's definitely a problem... Donal.
On May 26, 8:27 pm, Skip Gracely <s@hotmail.com> wrote: > [pid 6834] write(6, "", 0) = 0 > where I believe that 6 is the file descriptor of the telnet expect channel.
Just to be sure: 6834 is the expect process, right ? (look for excve()). Sounds fishy anyway, but if was the telnet child's deed, we'd be barking up the wrong tree :-) -Alex
Donal K. Fellows wrote: > Looks like it; writing zero-length buffers can cause some other problems
FWIW, way back when, writing a zero-length buffer was the defined way of truncating a file at the current seek position. Kind of a kludge until other APIs got implemented. -- Darren New / San Diego, CA, USA (PST) His kernel fu is strong. He studied at the Shao Linux Temple.
On May 25, 2:18 pm, Skip Gracely <s@hotmail.com> wrote:
> I'm getting the following error when I run a simple expect script: > "write() failed to write anything - will sleep(1) and retry..." > It happens when the script exits, so it's not really a problem > aside from having to wait for the sleep(1) to occur. It is more of > an annoyance in my real script (not shown) because I spawn six > telnet sessions, so I have to wait six sleep(1) times. > I'm running expect version 5.43.0 on Ubuntu 6.10 on a > 2.6.17-11-generic linux kernel. > Here's my six line script: > #!/usr/bin/expect > exp_internal 1 > set prompt "foo>" > spawn telnet "10.1.1.1" > expect -re $prompt > send "blah\r" > expect -re $prompt {} > Any help would be appreciated. > # email address not real - no spam
Are you sending exit to end the session Like: exp_send -i $spawnid "exit\r" this may not clean up the children processes you should always wait for the eof or timeout and if you timeout then you should kill the children then harvest the children. Like so set pid [spawn telnet $ipaddr ] set sp_id $spawn_id # do your work here .... # now exit exp_send -i $sp_id "\r" ; # get the prompt again set timeout 10 expect { -i $sp_id -re "$prompt" { exp_send "exit\r" exp_continue; # we continue because we want eof or timeout } timeout { exec kill -9 $pid exp_continue ; # optional with -9 its dead } eof { ; } }
# now cleanup harvest the child by "waiting" for it otherwise it becomes a zombie puts " Exit status : [ exp_wait -i $sp_id ]" catch { exp_close -i $sp_id } Note I just typed this in the browser so you may need to adjust... Carl
On Tue, 29 May 2007 07:56:45 -0700, Bezoar wrote: > On May 25, 2:18 pm, Skip Gracely <s @hotmail.com> wrote: >> I'm getting the following error when I run a simple expect script: >> "write() failed to write anything - will sleep(1) and retry..." >> It happens when the script exits, so it's not really a problem >> aside from having to wait for the sleep(1) to occur. It is more of >> an annoyance in my real script (not shown) because I spawn six >> telnet sessions, so I have to wait six sleep(1) times. >> I'm running expect version 5.43.0 on Ubuntu 6.10 on a >> 2.6.17-11-generic linux kernel. >> Here's my six line script: >> #!/usr/bin/expect >> exp_internal 1 >> set prompt "foo>" >> spawn telnet "10.1.1.1" >> expect -re $prompt >> send "blah\r" >> expect -re $prompt {} >> Any help would be appreciated. >> # email address not real - no spam > Are you sending exit to end the session Like: > exp_send -i $spawnid "exit\r" > this may not clean up the children processes you should always wait > for the eof or timeout and > if you timeout then you should kill the children then harvest the > children. Like so > set pid [spawn telnet $ipaddr ] > set sp_id $spawn_id > # do your work here > .... > # now exit > exp_send -i $sp_id "\r" ; # get the prompt again > set timeout 10 > expect { > -i $sp_id > -re "$prompt" { > exp_send "exit\r" > exp_continue; # we continue because we want eof or timeout > } > timeout { > exec kill -9 $pid > exp_continue ; # optional with -9 its dead > } > eof { > ; > } > } > # now cleanup harvest the child by "waiting" for it otherwise it > becomes a zombie > puts " Exit status : [ exp_wait -i $sp_id ]" > catch { exp_close -i $sp_id } > Note I just typed this in the browser so you may need to adjust... > Carl
I was assuming that expect would manage the shutdown on its own. Bad assumption? It seems to me that I should be able to just have an "exit" instruction that would send eof, wait for the children processes to exit, and read their status so as not to create zombies. I also think an implied "exit", meaning the end of the script was reached with no explicit "exit" instruction, should do the same.
On May 29, 4:31 pm, Skip Gracely <s@hotmail.com> wrote:
> On Tue, 29 May 2007 07:56:45 -0700, Bezoar wrote: > > On May 25, 2:18 pm, Skip Gracely <s @hotmail.com> wrote: > >> I'm getting the following error when I run a simple expect script: > >> "write() failed to write anything - will sleep(1) and retry..." > >> It happens when the script exits, so it's not really a problem > >> aside from having to wait for the sleep(1) to occur. It is more of > >> an annoyance in my real script (not shown) because I spawn six > >> telnet sessions, so I have to wait six sleep(1) times. > >> I'm running expect version 5.43.0 on Ubuntu 6.10 on a > >> 2.6.17-11-generic linux kernel. > >> Here's my six line script: > >> #!/usr/bin/expect > >> exp_internal 1 > >> set prompt "foo>" > >> spawn telnet "10.1.1.1" > >> expect -re $prompt > >> send "blah\r" > >> expect -re $prompt {} > >> Any help would be appreciated. > >> # email address not real - no spam > > Are you sending exit to end the session Like: > > exp_send -i $spawnid "exit\r" > > this may not clean up the children processes you should always wait > > for the eof or timeout and > > if you timeout then you should kill the children then harvest the > > children. Like so > > set pid [spawn telnet $ipaddr ] > > set sp_id $spawn_id > > # do your work here > > .... > > # now exit > > exp_send -i $sp_id "\r" ; # get the prompt again > > set timeout 10 > > expect { > > -i $sp_id > > -re "$prompt" { > > exp_send "exit\r" > > exp_continue; # we continue because we want eof or timeout > > } > > timeout { > > exec kill -9 $pid > > exp_continue ; # optional with -9 its dead > > } > > eof { > > ; > > } > > } > > # now cleanup harvest the child by "waiting" for it otherwise it > > becomes a zombie > > puts " Exit status : [ exp_wait -i $sp_id ]" > > catch { exp_close -i $sp_id } > > Note I just typed this in the browser so you may need to adjust... > > Carl > I was assuming that expect would manage the shutdown on its > own. Bad assumption? > It seems to me that I should be able to just have an "exit" instruction > that would send eof, wait for the children processes to exit, and > read their status so as not to create zombies. I also think an implied > "exit", meaning the end of the script was reached with no explicit "exit" > instruction, should do the same.
Yes it was a bad assumption. If you do not close and wait for your spawns you will eventually run out of spawn_ids . Usually this is not a problem since most scripts dont stay active for long periods and upon completion the OS will clean up any zombies and any open file descriptors. Carl
On May 30, 2:15 am, Bezoar <cwjo@gmail.com> wrote:
> On May 29, 4:31 pm, Skip Gracely <s @hotmail.com> wrote: > > On Tue, 29 May 2007 07:56:45 -0700, Bezoar wrote: > > > On May 25, 2:18 pm, Skip Gracely <s@hotmail.com> wrote: > > >> I'm getting the following error when I run a simple expect script: > > >> "write() failed to write anything - will sleep(1) and retry..." > > >> It happens when the script exits, so it's not really a problem > > >> aside from having to wait for the sleep(1) to occur. It is more of > > >> an annoyance in my real script (not shown) because I spawn six > > >> telnet sessions, so I have to wait six sleep(1) times. > > >> I'm running expect version 5.43.0 on Ubuntu 6.10 on a > > >> 2.6.17-11-generic linux kernel. > > >> Here's my six line script: > > >> #!/usr/bin/expect > > >> exp_internal 1 > > >> set prompt "foo>" > > >> spawn telnet "10.1.1.1" > > >> expect -re $prompt > > >> send "blah\r" > > >> expect -re $prompt {} > > >> Any help would be appreciated. > > >> # email address not real - no spam > > > Are you sending exit to end the session Like: > > > exp_send -i $spawnid "exit\r" > > > this may not clean up the children processes you should always wait > > > for the eof or timeout and > > > if you timeout then you should kill the children then harvest the > > > children. Like so > > > set pid [spawn telnet $ipaddr ] > > > set sp_id $spawn_id > > > # do your work here > > > .... > > > # now exit > > > exp_send -i $sp_id "\r" ; # get the prompt again > > > set timeout 10 > > > expect { > > > -i $sp_id > > > -re "$prompt" { > > > exp_send "exit\r" > > > exp_continue; # we continue because we want eof or timeout > > > } > > > timeout { > > > exec kill -9 $pid > > > exp_continue ; # optional with -9 its dead > > > } > > > eof { > > > ; > > > } > > > } > > > # now cleanup harvest the child by "waiting" for it otherwise it > > > becomes a zombie > > > puts " Exit status : [ exp_wait -i $sp_id ]" > > > catch { exp_close -i $sp_id } > > > Note I just typed this in the browser so you may need to adjust... > > > Carl > > I was assuming that expect would manage the shutdown on its > > own. Bad assumption? > > It seems to me that I should be able to just have an "exit" instruction > > that would send eof, wait for the children processes to exit, and > > read their status so as not to create zombies. I also think an implied > > "exit", meaning the end of the script was reached with no explicit "exit" > > instruction, should do the same. > Yes it was a bad assumption. If you do not close and wait for your > spawns > you will eventually run out of spawn_ids . Usually this is not a > problem since > most scripts dont stay active for long periods and upon completion the > OS will > clean up any zombies and any open file descriptors.
Does this explain the write(0) ? -Alex
|
 |
 |
 |
 |
|