0

I have a program that has ill effects if run from .bashrc and I've dug deeper and found a minimal reproducible example.

The code below will print the elapsed time every second. If I run this program any time well after boot it outputs sequential seconds, as expected. If I run this program immediately after boot, manually or with .bashrc, the seconds in the output will skip at some point; from .bashrc at 24 they skip to 37 (then continue on as expected 38, 39...), if I run it manually from a shell it happens at some earlier time, depending on how long after boot I run it.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main (int argc, char *argv[])
{
    int start_time = time(NULL);
    int diff = 0;
    int prev = 0;

    while (1)
    {
        diff = difftime(time(NULL), start_time);
        if (diff != prev)
        {
            printf("Time: %d\n", diff);
        }
        prev = diff;
    }
}

What could cause this?

user120300
  • 33
  • 6
  • 2
    Anything run from .bashrc is going to be a disaster because it is not intended to run code – Milliways Jan 08 '21 at 07:35
  • Why? What alternative do you suggest? Also, my problem occurs even if run manually shortly after boot. – user120300 Jan 08 '21 at 07:37
  • No one can suggest an "alternative" because it is pointless. – Milliways Jan 08 '21 at 07:39
  • How do you then automatically run a program at start? – user120300 Jan 08 '21 at 07:40
  • It depends on what the code is intended to do. There are literally hundreds of similar questions on this site. – Milliways Jan 08 '21 at 07:43
  • 1
    .bashrc has nothing to do with "at start" .... .bashrc is what is done on user login – Jaromanda X Jan 08 '21 at 07:43
  • > hundreds of similar questions - That's fine, I've seen numerous ways in various posts and articles, but bashrc has been presented as one of them. Why do you suggest otherwise? I do not understand what you think is pointless? – user120300 Jan 08 '21 at 07:48
  • I config the pi to autologin and bashrc is invoked. – user120300 Jan 08 '21 at 07:49
  • But forget bashrc, the issue in the post remains, even without bashrc – user120300 Jan 08 '21 at 07:50
  • @JaromandaX .bashrc is run every time a non-login bash shell starts. – Milliways Jan 08 '21 at 09:16
  • @Milliways - surely it's more complex than that ... .bashrc exists for every user :p – Jaromanda X Jan 08 '21 at 09:18
  • @JaromandaX `man bash` says " ~/.bash_profile The personal initialization(sic) file, executed for login shells ~/.bashrc The individual per-interactive-shell startup file" – Milliways Jan 08 '21 at 09:33
  • @user120300 If you want to start a program after booting, and you don't care about who (which user) starts the process, there is a thing called [rc.local](https://www.raspberrypi.org/documentation/linux/usage/rc-local.md). Note that if you don't start the process in the background, the bootup will be halted (no ssh) while the program is running, which may cause problems with an infinite loop. You could log the results into a file that you can access, and review the results, as there is no way to get the results from the standard output as far as I know. – nagyl Jan 08 '21 at 18:29

2 Answers2

2

First of all: I also suggest together with all others from the comments, don't use ~/.bashrc to start a still running program. The best way is to create a service with a systemd Unit file.

The problem with your program is that the Raspberry Pi does not have a real time clock. It needs an internet connection and some time after boot up to initialize the network and to synchronize the local time with a time server on the internet. That is exactly the point where you see the "jump" in the time and continuing as expected. To solve your problem just take into account the time until synchronization with a time server has finished. Have a look at How to know if time is synced?.

Ingo
  • 40,606
  • 15
  • 76
  • 189
  • Thank you. Is there some way to know when this synchronization is complete? As it stands this is part of a [larger problem](https://stackoverflow.com/questions/65613019/raspberry-pi-executing-program-from-bashrc-boot-gotchas) I am having and I thought this might be another indicator. Is there some way to see if all boot processes are complete? – user120300 Jan 08 '21 at 11:12
  • @user120300 I have updated the answer at the end. If you use systemd you have many options to check dependencies to other services. Depending on the user interface a boot up process is usually finished `After=multi-user.target` or `After=graphical.target` (see `man systemd.unit`). – Ingo Jan 08 '21 at 11:19
  • @user120300: [This recent Q&A](https://raspberrypi.stackexchange.com/questions/119793/how-to-make-sure-rtc-is-accurate) may help. – Seamus Jan 08 '21 at 19:43
  • @user120300 If this answer your question, please mark the answer as the accepted one with a click on the tick on its left side. That prevents your Question from being shown as an unsolved Post to the community and saves them/us a lot of work. – Ingo Jan 09 '21 at 09:20
1

As an alternative to @Ingo's excellent answer; i.e. "do not try to start a progrm in ~/.bashrc - create a systemd Unit file instead.":

Do not try to start a progrm in ~/.bashrc - create a cron job instead.

Complete instructions for setting up a cron job to start your program each time the RPi boots may be found here.

Seamus
  • 18,728
  • 2
  • 27
  • 57