I have a pi zero 1.3 running on an ethernet connection (using this hub hat). I am running it headless, so I can only access it via ssh. Every once in a while, the internet connection drops, and I have no choice but to unplug the device and plug it back in. Once it restarts, the connection works as normal.

I know that unplugging the device is bad, so I am trying to come up with a solution that will reestablish the connection automatically, or at least reboot if no connection is detected. I have written the following bash script and set it up as a cron job, but it doesn't seem to be working:

#Test for network connection
if [[ $(cat /sys/class/net/eth0/carrier) != 1 ]] #if eth0 is not connected
        date >> /home/pi/crons/net-check/log.txt #log date
        echo -e "\nNetwork connection down, restarting eth0..."
        ifconfig eth0 down && ifconfig eth0 up
        echo -e "Restart complete!\n"

        if [[ $(cat /sys/class/net/eth0/carrier) != 1 ]] #check if eth0 is still not connected
                echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" >> /home/pi/crons/net-check/log.txt #emphasize log date
                echo -e "Restart did not fix the issue, rebooting...\n"
                echo -e "Connection is up!\n"
        echo -e "\nConnection is up!\n"

I have not yet had the internet cut out on its own since setting this up. I attempted to test it by running sudo ifconfig eth0 down. As expected this kicks me off ssh, but it looks like the ifconfig eth0 up is not executing to restart the connection. The log file shows the ^^^^^^ (emphasizing that the connection was not reset), but the reboot does not execute either. Pinging the IP returns "host unreachable", and the logs look like this afterwards:

Log Message

The job is running in the root user crontab, so permissions should not be an issue. Here is how the task is set up:

* * * * * /home/pi/crons/net-check/net-check.sh

Any suggestions for why this might not be working? Any advice for logs to check to determine the source of the connection dropping would be helpful as well. Thanks!

  • 1
    Not everyone here can read minds, so you may get more help on troubleshooting if you could actually show us how you've set this up in your crontab. – Seamus Mar 31 at 20:19
  • I knew i was forgetting something! Updated. – Zach Taliaferro Mar 31 at 21:40
  • My comment was too long, so see the answer below. – Seamus Mar 31 at 22:34

Not sure exactly what's causing the issue, but a couple of things to try:

  1. the cron environment uses sh instead of bash AFAIR. Add SHELL=/bin/bash to crontab just before invoking your script.

  2. I think you may have a disconnect wrt where your script output is going. You redirect the date output in your script, but the echo output will go to stdout (aka /dev/null in cron env). This approach also loses the stderr output. Why not do your redirect from the crontab?

Now your crontab will look like this:

* * * * * /home/pi/crons/net-check/net-check.sh >> /home/pi/crons/net-check/log.txt 2>&1
  • 1. So after making this change, the crontab would look like * * * * * SHELL=/bin/bash /home/pi/crons/net-check/net-check.sh ? 2. If I understand you correctly, you are referring to the echo commands that are not sent to the log.txt file? Those were intended to help me with debugging while running the script from the command line. I left them in there for this reason. If you think they could lead to problems with the execution, I could remove them or comment them out. – Zach Taliaferro Apr 1 at 1:10
  • @ZachTaliaferro: uh, no - I didn't make that clear - see the edit. – Seamus Apr 1 at 7:57
  • 1
    WRT #2: exec &>> /home/pi/crons/net-check/log.txt is a good one to put at the top if you are using bash; this will redirect all subsequent stdout and stderr to that file. – goldilocks Apr 1 at 14:23
  • @goldilocks: Do you feel this is a sound approach given the OP's job is run in root's crontab? – Seamus Apr 1 at 18:06
  • 1
    The exec &> sugar has this hackish arcane quality to it -- it does't really jibe with what exec COMMAND means. It would have been a lot better if they put the functionality into something more straightforward like redirectAllOutputTo. Sometimes I think the secret motive behind (bash) shell syntax design is to maximize the ratio of punctuation symbols to alphabetic characters... – goldilocks Apr 1 at 22:48

ifconfig eth0 up is not executing to restart the connection

Because ifconfig set eth0 up does not create a connection; as man ifconfig explains:

up     This  flag  causes  the  interface  to be activated.

"Activated" means the interface is now ready to be used to make a connection. Exactly what this involves depends on the interface type, but the point is that it is a precondition of making a connection, sort of like how putting the keys in the ignition does not start the car, but you do have to do it first.

There may be software running in the background (eg. dhcpcd; I think this is the case in current stock RpiOS) that is triggered by the change in the interface state and responds to it by establishing a connection, but all by itself ifconfig ... up is no guarantee of that.

Any advice for logs to check to determine the source of the connection dropping would be helpful as well.

  • journalctl -u dhcpcd
  • systemd status dhcpcd
  • grep dhcpcd /var/log/syslog
  • This is very informative, thank you! I was definitely confused as to what the up/down commands were doing. Is there any way to have the script wait until the system has time to "turn the key" as you put it? I could add a sleep x but I'm sure there is a more elegant solution. Also, any ideas as to why the reboot did not execute? When I ran this from the command line to test it, everything seemed to work correctly. – Zach Taliaferro Apr 1 at 1:02
  • @ZachTaliaferro: wrt any ideas as to why the reboot did not execute: You may gain some insights by saving the stderr stream from your script to a log file. 2>&1 – Seamus Apr 1 at 18:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.