Thx for your response, alexander, I rewrote the function to reflect $sftp->error as a first best way to get useful error info from Net::SFTP::Foreign. As I started to test the new create directory, I did discover that having a plain file as the directory one wants to create causes an error, but I have played enough with this race condition that I don't want to play anymore. I'm reminded of John van Neumann's adage: "Don't play bad logic games."
I also made a first attempt at handling the error. One is left to ponder how an sftp method call to mkdir might fail and what a person with perl can do about it. It's common for the wireless to give out, as the laptop roams with me at tortoise speed. It's a hard thing to try to induce at a critical moment against the swiftness of machine instructions.
I'm going to revert to an architecture where I deal with the consequences of the mkdir as the critical path. I tried to write a code to remove the file, and wanted to try to do some other things if I lose my sftp connection. It's a big mess. I also tried to limit processes to reasonable amounts of time, but I haven't figured out how to handle $SIG{ALRM} yet, as none of these processes terminates. I'm gonna put abridged output and then source between readmore tags and pull out a couple issues.
First I fire up ssh to see what the next directory will be for this project. The highest existing directory is 1.hound5, so I know that my script is going to want to create a directory 1.hound6 . Instead, I create a plain text file:
(uiserver):u61210220:~/pmimage$ ls >1.hound6 (uiserver):u61210220:~/pmimage$ stat 1.hound6 File: ‘1.hound6’ Size: 1151 Blocks: 8 IO Block: 4096 regular file Device: 9405h/37893d Inode: 1021987444 Links: 1 Access: (0604/-rw----r--) Uid: (6042724/u61210220) Gid: ( 600/ftpu +sers) Access: 2018-11-22 00:23:27.844353135 -0500 Modify: 2018-11-22 00:23:27.844353135 -0500 Change: 2018-11-22 00:23:27.844353135 -0500 Birth: -
This is the output from the part of the script that uses sftp transfer:
Put file to server(y/n)?: y server dir is perlmonks return1 is Directory perlmonks already exists! path3 is /home/bob/2.scripts/pages/1.hound/template_stuff/1.hound1.css image dir is pmimage return2 is Directory pmimage already exists! Remove file(y/n)?: y you got 35 seconds for process 16757 return3 is 1 1.hound1.pl,16750 -w ./1.hound1.pl |-1.hound1.pl,16757 -w ./1.hound1.pl |-pstree,16758 -Apal 16750 `-ssh,16751 -p 22 -o NumberOfPasswordPrompts=1 -o PreferredAuthentic +ations=keyboard-interactive,password -l u61210220 home349337426.1and1 +-data.host -s sftp process 16757 executed here 16757 terminated ^C $
Here are the subroutines responsible for this part of the script (remember, I said these were a wreck):
sub createDir { use 5.011; use Net::SFTP::Foreign; my ( $dirName, $sftp ) = @_; if ( $sftp->test_e($dirName) ) { if ( !$sftp->test_d($dirName) ) { print "Remove file(y/n)?: "; my $prompt1 = <STDIN>; chomp $prompt1; if ( $prompt1 eq ( "y" | "Y" ) ) { my $start = time; if ( fork() == 0 ) { # arm the alarm clock alarm(35); say "you got 35 seconds for process $$"; # create a child process my $return3 = $sftp->remove($dirName); say "return3 is remove file return: $return3"; createDir( $dirName, $sftp ); say "process $$ executed here"; exit(0); } system("pstree -Apal $$"); while ( ( my $pid = wait() ) != -1 ) { say "$pid terminated"; } say time - $start, " seconds elapsed instead of a year"; } #end if that tests !$sftp->test_d($dirName) next brace } if ( $sftp->test_d($dirName) ) { return "Directory $dirName already exists!"; } else { say "Can't create $dirName because there's a file in the way!"; handleDirCreateError( @_, $sftp->error() ); } } my $success = $sftp->mkdir($dirName) or handleDirCreateError( @_, $sftp->error() ); return $success; } sub handleDirCreateError { use 5.011; use Net::SFTP::Foreign; my ( $dirName, $sftp, $error ) = @_; say "parameter array is @_"; if ( fork() == 0 ) { # arm the alarm clock alarm(10); say "alarm set for ten in process $$ and pinging google"; # create a child process my $trial = system("ping www.google.com"); say "trial is $trial"; exit(0); } print "Bounce wireless(y/n)?: "; my $prompt1 = <STDIN>; chomp $prompt1; if ( $prompt1 eq ( "y" | "Y" ) ) { if ( fork() == 0 ) { # arm the alarm clock alarm(35); say "alarm set for 35 in process $$ and restarting network"; # create a child process my $trial2 = system("sudo service network-manager restart"); say "trial2 is $trial2"; sleep 30; say "sleeping 30"; exit(0); } } print "Do you think you're ready now(y/n)?: "; my $prompt2 = <STDIN>; chomp $prompt2; if ( $prompt2 eq ( "y" | "Y" ) ) { my $return2 = createDir( $dirName, $sftp ); say "return2 is $return2"; } else { say "$error was too much this time: ceasing execution"; die; } return "execution shouldn't get here"; }
At the end, I do get my directory, but program execution has not continued so as to populate it.
(uiserver):u61210220:~/pmimage/1.hound6$ pwd /kunden/homepages/9/d349337426/htdocs/pmimage/1.hound6 (uiserver):u61210220:~/pmimage/1.hound6$
Let me just ask: do people ping anymore, or is that an old-fashioned way to see if one has internet connectivity? For example, I pinged perlmonks and got no answer, and had my terminal tied up. Might a person use curl instead?
What would I have to add for any of those alarms to terminate the process in which they are set?
Thanks all for comments
In reply to Re^3: using online translation engines with perl
by Aldebaran
in thread using online translation engines with perl
by Aldebaran
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |