#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    16
    Rep Power
    0

    Trying to start wvdial in the background from a perl script??


    Hello

    I am trying to write a script that will test if pppd is running. This indicates a wireless WAN connection is open.

    If the connection is closed, I want the script to run wvdial in the background. After waiting (10sec) to allow plenty of time for pppd to open a new connection, I do a test to see if the connection attempt was successful.

    It the attempt failed, I want to reboot the server. This script is a last ditch attempt to reopen the wireless connection. I have Autoreconnect configured in wvdial and that works. On one occasion it failed to reconnect, so this script runs once an hour to check if the connection is open.

    Below is a stripped down extract from the script that I run for testing.

    Code:
    #!/usr/bin/perl
    #
    
    use strict;
    use warnings;
    
      system "wvdial > /dev/null &" ;  # if pppd isn't running, run wvdial
      sleep 10;  #allow lots of time for pppd (wvdial) to restart
    
    my $exists = kill 0, `head -1 /var/run/ppp0.pid`;  # is pppd now running
    
    unless ($exists) { exec('reboot')}
    When I run this in perl debugger, wvdial runs and the connection is opened but it doesn't go into the background. I have to terminate wvdial with Ctrl-C from within the debugger.

    When I run this script from the command line, it returns immediately to the prompt which indicates that the
    Code:
    sleep 10
    never runs. The server does not reboot.

    So my immediate problem is that I can't get wvdial to run in the background from within the perl script. There are lots of articles on the web about starting processes in the background but it doesn't work for me.

    Help please.
  2. #2
  3. !~ /m$/
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    May 2004
    Location
    Reno, NV
    Posts
    4,264
    Rep Power
    1810
    Are you running the command as root, or a user?

    Also, you can try leaving out the > /dev/null portion. You are directing output to null, so not seeing what might be helpful feedback.

    Try your wvdial & from the command line rather than the script and make sure it works.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,968
    Rep Power
    1225
    Have you tried using fork()?
    Code:
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    my $pid = fork();
    if (defined $pid && $pid == 0) {
        exec "wvdial > /dev/null";
        exit;
    }
    
    sleep 10;
    my $exists = kill 0, `head -1 /var/run/ppp0.pid`;
    
    $exists or exec 'reboot';
    Last edited by FishMonger; August 31st, 2013 at 09:39 AM.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Location
    Paris area, France
    Posts
    843
    Rep Power
    496
    Running a Unix command in the background from a system "command" call definitely works. But the fact that you run it in the background means that the Perl script will not wait for the command to complete, because is sorts of sees the command to complete immediately.

    For example:

    Code:
    $ perl -e 'system "sleep 5"; print "foo\n"; sleep 5;'
    waits 5 seconds, prints "foo and wait again 5 seconds, while this:

    Code:
    $ perl -e 'system "sleep 5 & " ; print "foo\n"; sleep 5;'
    prints "foo" immediately, waits 5 seconds and exits.

    Another example with a benchmark program taking some time (about 15 seconds):

    Code:
    $ perl -e 'system "perl bench3.pl &"; print "foo\n"; sleep 2;'
    foo
    Benchmark: timing 100000 iterations of idiomatic, map...
    The script prints foo and the first line of the benchmarked program, waits 2 seconds and exits to the prompt. The rest of the benchmark information is printed much later (about 13 seconds later).



    So, it seems that it might be wvdial which is not doing what you want.

    Just one question: why do you want to run it in the background and then be forced to wait 10 seconds to make sure it completes? Wouldn't it be simpler to run in normally in the foreground?
    Last edited by Laurent_R; August 31st, 2013 at 02:01 PM.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    16
    Rep Power
    0
    Hi

    Yes, I run the script from the command line as root for testing.
    I have a cronjob set up to run this as root.

    I found an error in the reboot line. I used ' ...' instead of back ticks `...` or "..." . I have now used "..." for both linux commands.

    I have looked at fork but as far as I can tell it effectively runs a duplicate of the current script. The full version of this script does a bit more than shown in the stripped down version. All I want to be able to do is run wvdial in the background and/or run reboot.

    I have used the syslog function to log messages in the final version. This is for a headless remote web cam server so standard output is no use to me in the final version. At present the server is located in my house and I connect directly via PuTTY.

    After fixing the bugs, I found that I had to run the script using

    >perl test.pl

    This only seems to apply to this script and not the others I am running at the command line and from within crontab. I don't know why.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,968
    Rep Power
    1225
    I found an error in the reboot line. I used ' ...' instead of back ticks `...` or "..." . I have now used "..." for both linux commands.
    Using backticks in a system call is not what you want nor is it appropriate. You'd use backticks outside of a system call IF you need to capture the output of the command.

    If you don't need to interpolate any vars in the sysem call, then single quotes will work and be the most appropriate.

    Double quotes would be used if you need var interpolation.

    system vs fork
    Either can be used and in fact the system function actually does a fork to run the command. The advantage of doing the fork yourself is that you have more control over the overall process, which is why it's generally the preferred approach.

    After fixing the bugs, I found that I had to run the script using

    >perl test.pl

    This only seems to apply to this script and not the others I am running at the command line and from within crontab. I don't know why.
    The most likely cause is a problem with the shebang line.
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    16
    Rep Power
    0
    Hi
    I ran a dos2unix command over the source file and that fixed the problem with the shebang line.

    I can now run the command without a perl prefix.
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Location
    Paris area, France
    Posts
    843
    Rep Power
    496
    Originally Posted by dazz100
    I have looked at fork but as far as I can tell it effectively runs a duplicate of the current script.
    Yes, that's what fork is about, essentially running a copy of the same process But once you have forked, you usually have a condition in which you say, in effect: if I am the child, I do this, and if I am the parent, I do something else.

    Having said that, I think that have never used fork in Perl, except for a quick test. I have used fork for real things only in C.
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    16
    Rep Power
    0
    Hi

    I have written a script that pings highly reliable servers to determine if there is an open connection to the internet. I try pinging about 5 sites. If none of them respond, then I call a reboot.

    This test is run once per hour (cron). This means the system isn't swamped with reboots if there is a network service failure. The reboot is a last ditch attempt to connect to the internet.

    This script is in addition to the auto restart feature enabled in wvdial. Typically the network drops the connection at least once per day. This is so regular that I am sure the telecom network does it on purpose to disconnect latent modems. About 99% of the time, wvdial immediately reconnects after the drop out.

    For the rare occasions when wvdial fails to reconnect, the perl script checks for connectivity and if necessary, does a reboot. I know rebooting the server is not ideal but this has proven to be a reliable way of getting connected again.

IMN logo majestic logo threadwatch logo seochat tools logo