From: Chris M. <mut...@mc...> - 2003-09-14 21:28:58
|
Hi, I am working on a script that daemonizes and then uses ssh to login/operate/logout of a remote machine. The code works perfectly when it is not demonized, (with the demonization code commented out). The script will run and partially work if the code (the lines indicated below) is left in,-- it will fork, detach, and sleep but fail to get the command prompt on the remote machine. I have it log to a file (LOG_FILE), because when it is daemonized I cannot see the output. The only thing I can think of is that ssh must do something to the terminal/console that works when I run it manually on the console, but when the program is daemonized, ssh cannot do whatever it is trying to do and fails. The segment below fails saying "never got command prompt". This means that it got the password prompt from the remote machine and sent the password, but never got the command prompt after that. I don't think this is an expect problem, I think that it is a problem with how ssh and expect work together. My guess is that ssh is not intentionally failing, but it is trying to do something that does not work with the terminal that expect uses. I have even tried "ssh -l root" to specify the username, "ssh -T" so ssh won't allocate a pseudo-tty, and not setting the pty to raw; all to no avail. Does anyone have any ideas? Below is the code segment. Thanks, -Chris Muth #!/usr/bin/perl5.8 -w #prompt user for host to login to, and password print"host: ";$host=3D<STDIN>;chomp$host; print"pass: ";$pass=3D<STDIN>;chomp$pass; use Expect; use POSIX; # Comment out daemonizing code starting here ####################################### $pid =3D fork(); exit 0 if ($pid); POSIX::setsid(); close STDIN; close STDOUT; close STDERR; sleep 5; ####################################### # comment out daemonizing code ending here open (LOG_FILE, "> output"); # open log file $exp =3D new Expect; $exp->raw_pty(1); # login to the remote host #$exp->spawn("/usr/local/bin/ssh",'-T',"$host"); # Even tried ssh -T $exp->spawn("/usr/local/bin/ssh","$host"); # wait for Password: prompt $retval =3D $exp->expect(30,'-re','word:\s$'); if (!defined $retval){ print LOG_FILE "Never got password prompt\n"; flush LOG_FILE; } else { $exp->send("$pass\n"); #($retval,undef,$retstr,undef,undef) =3D $exp->expect(30,'stdin: is not= a tty'); # for ssh -T ($retval,undef,$retstr,undef,undef) =3D $exp->expect(30,'# '); # do something on the remote machine, test results if (!defined $retval){ print LOG_FILE "Never got command prompt\n"; flush LOG_FILE; } else { print LOG_FILE "\"$retstr\"\n"; flush LOG_FILE; $exp->send("echo Hello World\n"); $exp->expect(5,'This will make expect sleep for 5 seconds'); $exp->send("logout\n"); print LOG_FILE "It worked\n"; flush LOG_FILE; } } $exp->hard_close(); print LOG_FILE "\n"; flush LOG_FILE; close LOG_FILE; exit 0; |
From: John M. <ex...@h0...> - 2003-09-15 16:26:01
|
On Sun, Sep 14, 2003 at 04:27:52PM -0500, Chris Muth wrote: > Hi, > > I am working on a script that daemonizes and then uses > ssh to login/operate/logout of a remote machine. > > The code works perfectly when it is not demonized, (with the demonization > code commented out). The script will run and partially work if the > code (the lines indicated below) is left in,-- it will fork, detach, and > sleep but fail to get the command prompt on the remote machine. > I have it log to a file (LOG_FILE), because when it is daemonized I cannot > see the output. > > The only thing I can think of is that ssh must do something to the > terminal/console that works > when I run it manually on the console, but when the program > is daemonized, ssh cannot do whatever it is trying to do and fails. > > The segment below fails saying "never got command prompt". This means that > it got the password prompt from the remote machine > and sent the password, but never got the command prompt after that. > > I don't think this is an expect problem, I think that it is a problem with > how ssh and expect work together. > My guess is that ssh is not intentionally failing, but it is trying to do > something that does not work with the terminal that expect uses. > > I have even tried "ssh -l root" to specify the username, "ssh -T" so ssh > won't allocate a pseudo-tty, and not setting the pty to raw; all to no > avail. > > Does anyone have any ideas? > Below is the code segment. > > Thanks, > -Chris Muth > > > #!/usr/bin/perl5.8 -w > > #prompt user for host to login to, and password > print"host: ";$host=<STDIN>;chomp$host; > print"pass: ";$pass=<STDIN>;chomp$pass; > > use Expect; > use POSIX; > > # Comment out daemonizing code starting here > ####################################### > $pid = fork(); > exit 0 if ($pid); > > POSIX::setsid(); > close STDIN; > close STDOUT; > close STDERR; > > sleep 5; > ####################################### > # comment out daemonizing code ending here > > open (LOG_FILE, "> output"); # open log file > > $exp = new Expect; > $exp->raw_pty(1); > > # login to the remote host > #$exp->spawn("/usr/local/bin/ssh",'-T',"$host"); # Even tried ssh -T > $exp->spawn("/usr/local/bin/ssh","$host"); > > # wait for Password: prompt > $retval = $exp->expect(30,'-re','word:\s$'); > if (!defined $retval){ > print LOG_FILE "Never got password prompt\n"; flush LOG_FILE; > } else { > $exp->send("$pass\n"); > #($retval,undef,$retstr,undef,undef) = $exp->expect(30,'stdin: is not a tty'); # for ssh -T > ($retval,undef,$retstr,undef,undef) = $exp->expect(30,'# '); > > # do something on the remote machine, test results > if (!defined $retval){ > print LOG_FILE "Never got command prompt\n"; flush LOG_FILE; > } else { > print LOG_FILE "\"$retstr\"\n"; flush LOG_FILE; > $exp->send("echo Hello World\n"); > $exp->expect(5,'This will make expect sleep for 5 seconds'); > $exp->send("logout\n"); > print LOG_FILE "It worked\n"; flush LOG_FILE; > } > } > $exp->hard_close(); > print LOG_FILE "\n"; flush LOG_FILE; > close LOG_FILE; > exit 0; > > > > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > Expectperl-discuss mailing list > Exp...@li... > https://lists.sourceforge.net/lists/listinfo/expectperl-discuss Have you tried setting $Expect::Exp_Internal=1; before creating your expect object? This will produce a lot of debugging info that may help you locate the cause of your trouble. -- John _________________________________________________________ John Mahoney |
From: Chris M. <mut...@mc...> - 2003-09-15 19:12:10
|
Yes. I used that extensively when debugging the program that the fragment= in my original post came from. However, in this case, the script works perfectly when= running on the terminal and I can see the output of that ($Expect::Exp_Internal=3D1;), but when the script is= daemonized, there is no connection to the terminal to send output to. Note that in the fragment in my original post, I 'close STDOUT;'. I even tried something like the following. close STDOUT; open (STDOUT, "> log_file"); print "Hello, World!\n"; That worked. I was able to use standard print statements (that print to= STDOUT by default) to send stuff to the file, but any output from expect did not show up in= the file. I tried that again just now to be sure. I even tried opening STDERR to a= file. In both cases the program now hangs with a 0 length output file. It does not even say that it did not get the prompt. I know that is hung= as it showed up in `ps -eaf` for a longer time than any of its timeouts. Thanks for the idea though :-) -Chris Muth On 9/15/03 at 12:24 PM John Mahoney wrote: > >Have you tried setting > $Expect::Exp_Internal=3D1; >before creating your expect object? > >This will produce a lot of debugging info that may help >you locate the cause of your trouble. > >-- >John >_________________________________________________________ >John Mahoney |
From: <db...@CT...> - 2003-09-16 17:52:32
|
I'm wondering if spawning a "sh -c" to exec ssh instead of the ssh directly would work? i.e., something like: $exp->spawn("/bin/sh -c \"exec /usr/local/bin/ssh\"","$host"); Roland Giersig <RGi...@cp...> Sent by: To: exp...@li... exp...@li...urc cc: eforge.net Subject: Re: [Expectperl-discuss] ssh works from console but not once daemonized 09/16/2003 10:00 AM What system are you running on? You ARE using the latest version of IO::Tty, I suppose... The problem is: ssh is opening /dev/tty to read the password. If the script is started in a terminal session, /dev/tty is defined and Expect will redirect it for the spawned program to the pty, so the password prompt is seen. When the script is started via cron, there is no controlling terminal and obviously Expect cannot take control of it (it would have to create it), so ssh cannot get the password and thus fails. Even though I've had my share at kernel hacking, I do not know how to resolve this, especially given that this is probably highly system-dependend... Workaround: set up public key authentication for ssh, so ssh doesn't ask for a password. But then you'd probably won't need Expect at all... Hope this helps, Roland Chris Muth wrote: > Hi, > > I am working on a script that daemonizes and then uses > ssh to login/operate/logout of a remote machine. > > The code works perfectly when it is not demonized, (with the demonization > code commented out). The script will run and partially work if the > code (the lines indicated below) is left in,-- it will fork, detach, and > sleep but fail to get the command prompt on the remote machine. > I have it log to a file (LOG_FILE), because when it is daemonized I cannot > see the output. > > The only thing I can think of is that ssh must do something to the > terminal/console that works > when I run it manually on the console, but when the program > is daemonized, ssh cannot do whatever it is trying to do and fails. > > The segment below fails saying "never got command prompt". This means that > it got the password prompt from the remote machine > and sent the password, but never got the command prompt after that. > > I don't think this is an expect problem, I think that it is a problem with > how ssh and expect work together. > My guess is that ssh is not intentionally failing, but it is trying to do > something that does not work with the terminal that expect uses. > > I have even tried "ssh -l root" to specify the username, "ssh -T" so ssh > won't allocate a pseudo-tty, and not setting the pty to raw; all to no > avail. > > Does anyone have any ideas? > Below is the code segment. > > Thanks, > -Chris Muth > > > #!/usr/bin/perl5.8 -w > > #prompt user for host to login to, and password > print"host: ";$host=<STDIN>;chomp$host; > print"pass: ";$pass=<STDIN>;chomp$pass; > > use Expect; > use POSIX; > > # Comment out daemonizing code starting here > ####################################### > $pid = fork(); > exit 0 if ($pid); > > POSIX::setsid(); > close STDIN; > close STDOUT; > close STDERR; > > sleep 5; > ####################################### > # comment out daemonizing code ending here > > open (LOG_FILE, "> output"); # open log file > > $exp = new Expect; > $exp->raw_pty(1); > > # login to the remote host > #$exp->spawn("/usr/local/bin/ssh",'-T',"$host"); # Even tried ssh -T > $exp->spawn("/usr/local/bin/ssh","$host"); > > # wait for Password: prompt > $retval = $exp->expect(30,'-re','word:\s$'); > if (!defined $retval){ > print LOG_FILE "Never got password prompt\n"; flush LOG_FILE; > } else { > $exp->send("$pass\n"); > #($retval,undef,$retstr,undef,undef) = $exp->expect(30,'stdin: is not a tty'); # for ssh -T > ($retval,undef,$retstr,undef,undef) = $exp->expect(30,'# '); > > # do something on the remote machine, test results > if (!defined $retval){ > print LOG_FILE "Never got command prompt\n"; flush LOG_FILE; > } else { > print LOG_FILE "\"$retstr\"\n"; flush LOG_FILE; > $exp->send("echo Hello World\n"); > $exp->expect(5,'This will make expect sleep for 5 seconds'); > $exp->send("logout\n"); > print LOG_FILE "It worked\n"; flush LOG_FILE; > } > } > $exp->hard_close(); > print LOG_FILE "\n"; flush LOG_FILE; > close LOG_FILE; > exit 0; > > > > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > Expectperl-discuss mailing list > Exp...@li... > https://lists.sourceforge.net/lists/listinfo/expectperl-discuss > ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ Expectperl-discuss mailing list Exp...@li... https://lists.sourceforge.net/lists/listinfo/expectperl-discuss |
From: <db...@CT...> - 2003-09-16 18:33:35
|
actually, to be more correct: $exp->spawn("/bin/sh -c \"exec /usr/local/bin/ssh $host\""); db...@CT... Sent by: To: Chris Muth <mut...@mc...> exp...@li...urc cc: exp...@li..., eforge.net exp...@li... Subject: Re: [Expectperl-discuss] ssh works from console but not once daemonized 09/16/2003 01:51 PM I'm wondering if spawning a "sh -c" to exec ssh instead of the ssh directly would work? i.e., something like: $exp->spawn("/bin/sh -c \"exec /usr/local/bin/ssh\"","$host"); Roland Giersig <RGi...@cp...> Sent by: To: exp...@li... exp...@li...urc cc: eforge.net Subject: Re: [Expectperl-discuss] ssh works from console but not once daemonized 09/16/2003 10:00 AM What system are you running on? You ARE using the latest version of IO::Tty, I suppose... The problem is: ssh is opening /dev/tty to read the password. If the script is started in a terminal session, /dev/tty is defined and Expect will redirect it for the spawned program to the pty, so the password prompt is seen. When the script is started via cron, there is no controlling terminal and obviously Expect cannot take control of it (it would have to create it), so ssh cannot get the password and thus fails. Even though I've had my share at kernel hacking, I do not know how to resolve this, especially given that this is probably highly system-dependend... Workaround: set up public key authentication for ssh, so ssh doesn't ask for a password. But then you'd probably won't need Expect at all... Hope this helps, Roland Chris Muth wrote: > Hi, > > I am working on a script that daemonizes and then uses > ssh to login/operate/logout of a remote machine. > > The code works perfectly when it is not demonized, (with the demonization > code commented out). The script will run and partially work if the > code (the lines indicated below) is left in,-- it will fork, detach, and > sleep but fail to get the command prompt on the remote machine. > I have it log to a file (LOG_FILE), because when it is daemonized I cannot > see the output. > > The only thing I can think of is that ssh must do something to the > terminal/console that works > when I run it manually on the console, but when the program > is daemonized, ssh cannot do whatever it is trying to do and fails. > > The segment below fails saying "never got command prompt". This means that > it got the password prompt from the remote machine > and sent the password, but never got the command prompt after that. > > I don't think this is an expect problem, I think that it is a problem with > how ssh and expect work together. > My guess is that ssh is not intentionally failing, but it is trying to do > something that does not work with the terminal that expect uses. > > I have even tried "ssh -l root" to specify the username, "ssh -T" so ssh > won't allocate a pseudo-tty, and not setting the pty to raw; all to no > avail. > > Does anyone have any ideas? > Below is the code segment. > > Thanks, > -Chris Muth > > > #!/usr/bin/perl5.8 -w > > #prompt user for host to login to, and password > print"host: ";$host=<STDIN>;chomp$host; > print"pass: ";$pass=<STDIN>;chomp$pass; > > use Expect; > use POSIX; > > # Comment out daemonizing code starting here > ####################################### > $pid = fork(); > exit 0 if ($pid); > > POSIX::setsid(); > close STDIN; > close STDOUT; > close STDERR; > > sleep 5; > ####################################### > # comment out daemonizing code ending here > > open (LOG_FILE, "> output"); # open log file > > $exp = new Expect; > $exp->raw_pty(1); > > # login to the remote host > #$exp->spawn("/usr/local/bin/ssh",'-T',"$host"); # Even tried ssh -T > $exp->spawn("/usr/local/bin/ssh","$host"); > > # wait for Password: prompt > $retval = $exp->expect(30,'-re','word:\s$'); > if (!defined $retval){ > print LOG_FILE "Never got password prompt\n"; flush LOG_FILE; > } else { > $exp->send("$pass\n"); > #($retval,undef,$retstr,undef,undef) = $exp->expect(30,'stdin: is not a tty'); # for ssh -T > ($retval,undef,$retstr,undef,undef) = $exp->expect(30,'# '); > > # do something on the remote machine, test results > if (!defined $retval){ > print LOG_FILE "Never got command prompt\n"; flush LOG_FILE; > } else { > print LOG_FILE "\"$retstr\"\n"; flush LOG_FILE; > $exp->send("echo Hello World\n"); > $exp->expect(5,'This will make expect sleep for 5 seconds'); > $exp->send("logout\n"); > print LOG_FILE "It worked\n"; flush LOG_FILE; > } > } > $exp->hard_close(); > print LOG_FILE "\n"; flush LOG_FILE; > close LOG_FILE; > exit 0; > > > > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > Expectperl-discuss mailing list > Exp...@li... > https://lists.sourceforge.net/lists/listinfo/expectperl-discuss > ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ Expectperl-discuss mailing list Exp...@li... https://lists.sourceforge.net/lists/listinfo/expectperl-discuss ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ Expectperl-discuss mailing list Exp...@li... https://lists.sourceforge.net/lists/listinfo/expectperl-discuss |
From: Rogaski, M. A. <ro...@at...> - 2003-09-16 21:44:28
|
Would this work? $exp->spawn("/usr/local/bin/ssh -tt $host"); Mark -- Mark Rogaski "Computers save time like kudzu prevents Multi-service Data Field Support soil erosion." -- Al Castanoli email: ro...@at... voice: +1-732-885-7534 pager: +1-888-858-7243 p: 200853 or 20...@pa... -----Original Message----- From: db...@CT... [mailto:db...@CT...] Sent: Tuesday, September 16, 2003 2:33 PM To: Chris Muth Cc: exp...@li...; exp...@li... Subject: Re: [Expectperl-discuss] ssh works from console but not once daemonized actually, to be more correct: $exp->spawn("/bin/sh -c \"exec /usr/local/bin/ssh $host\""); =20 db...@CT... Sent by: To: Chris Muth <mut...@mc...> =20 exp...@li...urc cc: exp...@li..., =20 eforge.net exp...@li... =20 Subject: Re: [Expectperl-discuss] ssh works from =20 console but not once daemonized =20 09/16/2003 01:51 PM =20 =20 I'm wondering if spawning a "sh -c" to exec ssh instead of the ssh directly would work? i.e., something like: $exp->spawn("/bin/sh -c \"exec /usr/local/bin/ssh\"","$host"); Roland Giersig <RGi...@cp...> Sent by: To: exp...@li... exp...@li...urc cc: eforge.net Subject: Re: [Expectperl-discuss] ssh works from console but not once daemonized 09/16/2003 10:00 AM What system are you running on? You ARE using the latest version of IO::Tty, I suppose... The problem is: ssh is opening /dev/tty to read the password. If the script is started in a terminal session, /dev/tty is defined and Expect will redirect it for the spawned program to the pty, so the password prompt is seen. When the script is started via cron, there is no controlling terminal and obviously Expect cannot take control of it (it would have to create it), so ssh cannot get the password and thus fails. Even though I've had my share at kernel hacking, I do not know how to resolve this, especially given that this is probably highly system-dependend... Workaround: set up public key authentication for ssh, so ssh doesn't ask for a password. But then you'd probably won't need Expect at all... Hope this helps, Roland Chris Muth wrote: > Hi, > > I am working on a script that daemonizes and then uses > ssh to login/operate/logout of a remote machine. > > The code works perfectly when it is not demonized, (with the demonization > code commented out). The script will run and partially work if the > code (the lines indicated below) is left in,-- it will fork, detach, and > sleep but fail to get the command prompt on the remote machine. > I have it log to a file (LOG_FILE), because when it is daemonized I cannot > see the output. > > The only thing I can think of is that ssh must do something to the > terminal/console that works > when I run it manually on the console, but when the program > is daemonized, ssh cannot do whatever it is trying to do and fails. > > The segment below fails saying "never got command prompt". This means that > it got the password prompt from the remote machine > and sent the password, but never got the command prompt after that. > > I don't think this is an expect problem, I think that it is a problem with > how ssh and expect work together. > My guess is that ssh is not intentionally failing, but it is trying to do > something that does not work with the terminal that expect uses. > > I have even tried "ssh -l root" to specify the username, "ssh -T" so ssh > won't allocate a pseudo-tty, and not setting the pty to raw; all to no > avail. > > Does anyone have any ideas? > Below is the code segment. > > Thanks, > -Chris Muth > > > #!/usr/bin/perl5.8 -w > > #prompt user for host to login to, and password > print"host: ";$host=3D<STDIN>;chomp$host; > print"pass: ";$pass=3D<STDIN>;chomp$pass; > > use Expect; > use POSIX; > > # Comment out daemonizing code starting here > ####################################### > $pid =3D fork(); > exit 0 if ($pid); > > POSIX::setsid(); > close STDIN; > close STDOUT; > close STDERR; > > sleep 5; > ####################################### > # comment out daemonizing code ending here > > open (LOG_FILE, "> output"); # open log file > > $exp =3D new Expect; > $exp->raw_pty(1); > > # login to the remote host > #$exp->spawn("/usr/local/bin/ssh",'-T',"$host"); # Even tried ssh -T > $exp->spawn("/usr/local/bin/ssh","$host"); > > # wait for Password: prompt > $retval =3D $exp->expect(30,'-re','word:\s$'); > if (!defined $retval){ > print LOG_FILE "Never got password prompt\n"; flush LOG_FILE; > } else { > $exp->send("$pass\n"); > #($retval,undef,$retstr,undef,undef) =3D $exp->expect(30,'stdin: is not a tty'); # for ssh -T > ($retval,undef,$retstr,undef,undef) =3D $exp->expect(30,'# '); > > # do something on the remote machine, test results > if (!defined $retval){ > print LOG_FILE "Never got command prompt\n"; flush LOG_FILE; > } else { > print LOG_FILE "\"$retstr\"\n"; flush LOG_FILE; > $exp->send("echo Hello World\n"); > $exp->expect(5,'This will make expect sleep for 5 seconds'); > $exp->send("logout\n"); > print LOG_FILE "It worked\n"; flush LOG_FILE; > } > } > $exp->hard_close(); > print LOG_FILE "\n"; flush LOG_FILE; > close LOG_FILE; > exit 0; > > > > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > Expectperl-discuss mailing list > Exp...@li... > https://lists.sourceforge.net/lists/listinfo/expectperl-discuss > ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ Expectperl-discuss mailing list Exp...@li... https://lists.sourceforge.net/lists/listinfo/expectperl-discuss ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ Expectperl-discuss mailing list Exp...@li... https://lists.sourceforge.net/lists/listinfo/expectperl-discuss ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ Expectperl-discuss mailing list Exp...@li... https://lists.sourceforge.net/lists/listinfo/expectperl-discuss |
From: Roland G. <RGi...@cp...> - 2003-09-16 22:22:11
|
Rogaski, Mark, ALABS wrote: > Would this work? > > $exp->spawn("/usr/local/bin/ssh -tt $host"); No, the -t option forces tty-allocation at the remote (sshd server) side, we are talking about the client side here... Basically Expect would have to mimick what login or sshd is doing when allocating a pty. And it somewhat does (I got the pty allocation code partially from sshd). Hmm... there was some call that is only available to the superuser, maybe that's the missing one to correctly allocate the controlling tty... I left it out because it would only work for root, but maybe... I'll look into the issue when I have some spare time next week... Roland |
From: Austin S. <te...@of...> - 2003-09-17 04:55:48
|
On Tue, Sep 16, 2003 at 09:46:51PM -0500, Chris Muth wrote: > Hi, > > I am running; > Perl 5.8 > Expect 1.15 > IO::Tty 1.02 > IO::Stty .02 > Linux 2.2.20 > > I am not sure how cron figures into this, I am not using it for this script. > Haha.. that's what I get for not reading. I'm not sure where I thought you meant cron where you said daemonize. This script will work much better if you don't close stdin/stdout/stderr. They are inherited by the children when they start. I'm not sure why that is fouling stuff up, since they get reopened anyway, but it definitely is. Doing setsid() should make it so it doesn't die when the original terminal is closed, but you may want to do setpgrp() so it doesn't die when the parent (your shell) dies. Austin |
From: Chris M. <mut...@mc...> - 2003-09-17 15:02:17
|
NOT closing STDIN makes the fragment work properly. Thank You, Chris Muth On 9/16/03 at 9:55 PM Austin Schutz wrote: >On Tue, Sep 16, 2003 at 09:46:51PM -0500, Chris Muth wrote: >> Hi, >> >> I am running; >> Perl 5.8 >> Expect 1.15 >> IO::Tty 1.02 >> IO::Stty .02 >> Linux 2.2.20 >> >> I am not sure how cron figures into this, I am not using it for this >script. >> > > Haha.. that's what I get for not reading. I'm not sure where I thought >you meant cron where you said daemonize. This script will work much >better if you don't close stdin/stdout/stderr. They are inherited by the >children when they start. I'm not sure why that is fouling stuff up, since >they get reopened anyway, but it definitely is. > Doing setsid() should make it so it doesn't die when the original >terminal is closed, but you may want to do setpgrp() so it doesn't die= when >the parent (your shell) dies. > > Austin |
From: Chris M. <mut...@mc...> - 2003-09-17 15:00:16
|
YES! I did the same and the fragment works flawlessly. My little trick of closing then reopening STDOUT and STDERR to a file even works now :-) Thanks, Chris Muth On 9/16/03 at 9:24 PM expect wrote: > >I commented this > >#close STDIN; > > |
From: Roland G. <RGi...@cp...> - 2003-09-16 14:01:23
|
What system are you running on? You ARE using the latest version of IO::Tty, I suppose... The problem is: ssh is opening /dev/tty to read the password. If the script is started in a terminal session, /dev/tty is defined and Expect will redirect it for the spawned program to the pty, so the password prompt is seen. When the script is started via cron, there is no controlling terminal and obviously Expect cannot take control of it (it would have to create it), so ssh cannot get the password and thus fails. Even though I've had my share at kernel hacking, I do not know how to resolve this, especially given that this is probably highly system-dependend... Workaround: set up public key authentication for ssh, so ssh doesn't ask for a password. But then you'd probably won't need Expect at all... Hope this helps, Roland Chris Muth wrote: > Hi, > > I am working on a script that daemonizes and then uses > ssh to login/operate/logout of a remote machine. > > The code works perfectly when it is not demonized, (with the demonization > code commented out). The script will run and partially work if the > code (the lines indicated below) is left in,-- it will fork, detach, and > sleep but fail to get the command prompt on the remote machine. > I have it log to a file (LOG_FILE), because when it is daemonized I cannot > see the output. > > The only thing I can think of is that ssh must do something to the > terminal/console that works > when I run it manually on the console, but when the program > is daemonized, ssh cannot do whatever it is trying to do and fails. > > The segment below fails saying "never got command prompt". This means that > it got the password prompt from the remote machine > and sent the password, but never got the command prompt after that. > > I don't think this is an expect problem, I think that it is a problem with > how ssh and expect work together. > My guess is that ssh is not intentionally failing, but it is trying to do > something that does not work with the terminal that expect uses. > > I have even tried "ssh -l root" to specify the username, "ssh -T" so ssh > won't allocate a pseudo-tty, and not setting the pty to raw; all to no > avail. > > Does anyone have any ideas? > Below is the code segment. > > Thanks, > -Chris Muth > > > #!/usr/bin/perl5.8 -w > > #prompt user for host to login to, and password > print"host: ";$host=<STDIN>;chomp$host; > print"pass: ";$pass=<STDIN>;chomp$pass; > > use Expect; > use POSIX; > > # Comment out daemonizing code starting here > ####################################### > $pid = fork(); > exit 0 if ($pid); > > POSIX::setsid(); > close STDIN; > close STDOUT; > close STDERR; > > sleep 5; > ####################################### > # comment out daemonizing code ending here > > open (LOG_FILE, "> output"); # open log file > > $exp = new Expect; > $exp->raw_pty(1); > > # login to the remote host > #$exp->spawn("/usr/local/bin/ssh",'-T',"$host"); # Even tried ssh -T > $exp->spawn("/usr/local/bin/ssh","$host"); > > # wait for Password: prompt > $retval = $exp->expect(30,'-re','word:\s$'); > if (!defined $retval){ > print LOG_FILE "Never got password prompt\n"; flush LOG_FILE; > } else { > $exp->send("$pass\n"); > #($retval,undef,$retstr,undef,undef) = $exp->expect(30,'stdin: is not a tty'); # for ssh -T > ($retval,undef,$retstr,undef,undef) = $exp->expect(30,'# '); > > # do something on the remote machine, test results > if (!defined $retval){ > print LOG_FILE "Never got command prompt\n"; flush LOG_FILE; > } else { > print LOG_FILE "\"$retstr\"\n"; flush LOG_FILE; > $exp->send("echo Hello World\n"); > $exp->expect(5,'This will make expect sleep for 5 seconds'); > $exp->send("logout\n"); > print LOG_FILE "It worked\n"; flush LOG_FILE; > } > } > $exp->hard_close(); > print LOG_FILE "\n"; flush LOG_FILE; > close LOG_FILE; > exit 0; > > > > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > Expectperl-discuss mailing list > Exp...@li... > https://lists.sourceforge.net/lists/listinfo/expectperl-discuss > |
From: Austin S. <te...@of...> - 2003-09-16 19:29:16
|
On Sun, Sep 14, 2003 at 04:27:52PM -0500, Chris Muth wrote: > Does anyone have any ideas? The following code snippet works fine for me when called from cron. I recall having problems using expect with early versions of ssh. Perhaps you could tell us your OS, ssh, Expect, and IO::Tty versions? Btw, in reponse to a couple other postings, Expect uses IO::Tty to create a tty to run the command in and sets its controlling terminal to the tty it creates. Reads and writes to /dev/tty should work just fine. That's the idea anyway, and it works here just fine. I'm using: Expect v. 1.15, IO::Tty v. 1.00, perl 5.6.1, ssh OpenSSH_3.5p1, Linux, kernel ver. 2.4.20 Austin #!/usr/bin/perl -w use Expect; $ssh = new Expect; $ssh->spawn("/usr/local/bin/ssh", "localhost"); $ssh->expect(10, "password: "); print $ssh "$ARGV[0]\n"; $ssh->expect(10, '$' ); |
From: Chris M. <mut...@mc...> - 2003-09-17 02:48:15
|
Hi, I am running; Perl 5.8 Expect 1.15 IO::Tty 1.02 IO::Stty .02 Linux 2.2.20 I am not sure how cron figures into this, I am not using it for this= script. As I mentioned in my original post, I had kind of thought that the problem= was that ssh was not working properly with expect/my script once daemonized. Am I correct in guessing that ssh opening /dev/tty to read the password= because that is more secure than simply reading stdin? If this is the case, I might be= able to simply modify ssh to just read from stdin. What do you think? Thanks, Chris Muth On 9/16/03 at 3:53 PM Roland Giersig wrote: >What system are you running on? You ARE using the latest version of >IO::Tty, I suppose... > >The problem is: ssh is opening /dev/tty to read the password. If the >script is started in a terminal session, /dev/tty is defined and Expect >will redirect it for the spawned program to the pty, so the password >prompt is seen. > >When the script is started via cron, there is no controlling terminal >and obviously Expect cannot take control of it (it would have to create >it), so ssh cannot get the password and thus fails. > >Even though I've had my share at kernel hacking, I do not know how to >resolve this, especially given that this is probably highly >system-dependend... > >Workaround: set up public key authentication for ssh, so ssh doesn't ask >for a password. But then you'd probably won't need Expect at all... > >Hope this helps, > >Roland > >Chris Muth wrote: > >> Hi, >> >> I am working on a script that daemonizes and then uses >> ssh to login/operate/logout of a remote machine. >> >> The code works perfectly when it is not demonized, (with the= demonization >> code commented out). The script will run and partially work if the >> code (the lines indicated below) is left in,-- it will fork, detach, and >> sleep but fail to get the command prompt on the remote machine. >> I have it log to a file (LOG_FILE), because when it is daemonized I >cannot >> see the output. >> >> The only thing I can think of is that ssh must do something to the >> terminal/console that works >> when I run it manually on the console, but when the program >> is daemonized, ssh cannot do whatever it is trying to do and fails. >> >> The segment below fails saying "never got command prompt". This means >that >> it got the password prompt from the remote machine >> and sent the password, but never got the command prompt after that. >> >> I don't think this is an expect problem, I think that it is a problem >with >> how ssh and expect work together. >> My guess is that ssh is not intentionally failing, but it is trying to= do >> something that does not work with the terminal that expect uses. >> >> I have even tried "ssh -l root" to specify the username, "ssh -T" so ssh >> won't allocate a pseudo-tty, and not setting the pty to raw; all to no >> avail. >> >> Does anyone have any ideas? >> Below is the code segment. >> >> Thanks, >> -Chris Muth >> >> >> #!/usr/bin/perl5.8 -w >> >> #prompt user for host to login to, and password >> print"host: ";$host=3D<STDIN>;chomp$host; >> print"pass: ";$pass=3D<STDIN>;chomp$pass; >> >> use Expect; >> use POSIX; >> >> # Comment out daemonizing code starting here >> ####################################### >> $pid =3D fork(); >> exit 0 if ($pid); >> >> POSIX::setsid(); >> close STDIN; >> close STDOUT; >> close STDERR; >> >> sleep 5; >> ####################################### >> # comment out daemonizing code ending here >> >> open (LOG_FILE, "> output"); # open log file >> >> $exp =3D new Expect; >> $exp->raw_pty(1); >> >> # login to the remote host >> #$exp->spawn("/usr/local/bin/ssh",'-T',"$host"); # Even tried ssh -T >> $exp->spawn("/usr/local/bin/ssh","$host"); >> >> # wait for Password: prompt >> $retval =3D $exp->expect(30,'-re','word:\s$'); >> if (!defined $retval){ >> print LOG_FILE "Never got password prompt\n"; flush LOG_FILE; >> } else { >> $exp->send("$pass\n"); >> #($retval,undef,$retstr,undef,undef) =3D $exp->expect(30,'stdin: is= not >a tty'); # for ssh -T >> ($retval,undef,$retstr,undef,undef) =3D $exp->expect(30,'# '); >> >> # do something on the remote machine, test results >> if (!defined $retval){ >> print LOG_FILE "Never got command prompt\n"; flush LOG_FILE; >> } else { >> print LOG_FILE "\"$retstr\"\n"; flush LOG_FILE; >> $exp->send("echo Hello World\n"); >> $exp->expect(5,'This will make expect sleep for 5 seconds'); >> $exp->send("logout\n"); >> print LOG_FILE "It worked\n"; flush LOG_FILE; >> } >> } >> $exp->hard_close(); >> print LOG_FILE "\n"; flush LOG_FILE; >> close LOG_FILE; >> exit 0; >> >> >> >> >> ------------------------------------------------------- >> This sf.net email is sponsored by:ThinkGeek >> Welcome to geek heaven. >> http://thinkgeek.com/sf >> _______________________________________________ >> Expectperl-discuss mailing list >> Exp...@li... >> https://lists.sourceforge.net/lists/listinfo/expectperl-discuss >> |
From: Chris M. <mut...@mc...> - 2003-09-17 03:00:48
|
Whoops, I forgot to mention I am running OpenSSH_3.4p1 -Chris Muth |
From: expect <ex...@ih...> - 2003-09-17 04:24:34
|
On Sun, 14 Sep 2003 16:27:52 -0500 "Chris Muth" <mut...@mc...> wrote: > Hi, > > I am working on a script that daemonizes and then uses > ssh to login/operate/logout of a remote machine. > > The code works perfectly when it is not demonized, (with the demonization > code commented out). The script will run and partially work if the > code (the lines indicated below) is left in,-- it will fork, detach, and > sleep but fail to get the command prompt on the remote machine. > I have it log to a file (LOG_FILE), because when it is daemonized I cannot > see the output. > > The only thing I can think of is that ssh must do something to the > terminal/console that works > when I run it manually on the console, but when the program > is daemonized, ssh cannot do whatever it is trying to do and fails. > > The segment below fails saying "never got command prompt". This means that > it got the password prompt from the remote machine > and sent the password, but never got the command prompt after that. > > I don't think this is an expect problem, I think that it is a problem with > how ssh and expect work together. > My guess is that ssh is not intentionally failing, but it is trying to do > something that does not work with the terminal that expect uses. > > I have even tried "ssh -l root" to specify the username, "ssh -T" so ssh > won't allocate a pseudo-tty, and not setting the pty to raw; all to no > avail. > > Does anyone have any ideas? > Below is the code segment. > > Thanks, > -Chris Muth > > > #!/usr/bin/perl5.8 -w > > #prompt user for host to login to, and password > print"host: ";$host=<STDIN>;chomp$host; > print"pass: ";$pass=<STDIN>;chomp$pass; > > use Expect; $Expect::Debug = 1; > use POSIX; > > # Comment out daemonizing code starting here > ####################################### > $pid = fork(); > exit 0 if ($pid); > > POSIX::setsid(); > close STDIN; I commented this #close STDIN; > close STDOUT; > close STDERR; > > sleep 5; > ####################################### > # comment out daemonizing code ending here > > open (LOG_FILE, "> output"); # open log file > > $exp = new Expect; > $exp->raw_pty(1); > > # login to the remote host > #$exp->spawn("/usr/local/bin/ssh",'-T',"$host"); # Even tried ssh -T > $exp->spawn("/usr/local/bin/ssh","$host"); and had to do this (probably not pertinent to your problem) $exp->spawn("/usr/local/bin/ssh","usernameonremotehost\@$host"); And it worked. If it's not suitable as a solution it should provide the clue. > > # wait for Password: prompt > $retval = $exp->expect(30,'-re','word:\s$'); > if (!defined $retval){ > print LOG_FILE "Never got password prompt\n"; flush LOG_FILE; > } else { > $exp->send("$pass\n"); > #($retval,undef,$retstr,undef,undef) = $exp->expect(30,'stdin: is not a tty'); # for ssh -T > ($retval,undef,$retstr,undef,undef) = $exp->expect(30,'# '); > > # do something on the remote machine, test results > if (!defined $retval){ > print LOG_FILE "Never got command prompt\n"; flush LOG_FILE; > } else { > print LOG_FILE "\"$retstr\"\n"; flush LOG_FILE; > $exp->send("echo Hello World\n"); > $exp->expect(5,'This will make expect sleep for 5 seconds'); > $exp->send("logout\n"); > print LOG_FILE "It worked\n"; flush LOG_FILE; > } > } > $exp->hard_close(); > print LOG_FILE "\n"; flush LOG_FILE; > close LOG_FILE; > exit 0; > > > > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > Expectperl-discuss mailing list > Exp...@li... > https://lists.sourceforge.net/lists/listinfo/expectperl-discuss > > |
From: Chris M. <mut...@mc...> - 2003-09-17 19:29:30
|
Hi, Thank you all very much, I really appreciate it. :-) -Chris Muth |