Recent

Author Topic: [Linux] Program that runs in the background  (Read 1996 times)

abdoun.brahim

  • New member
  • *
  • Posts: 9
[Linux] Program that runs in the background
« on: May 11, 2022, 06:21:42 pm »
Hello

I want to create a Lazarus Linux program in console mode that will run in the background (without seeing the result on the screen): it is a program that will run in the background and that will play on the serial port; the traces of communications will be recorded in a log file and the data captured in a PostgreSQL database.

Thank you for your help.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: [Linux] Program that runs in the background
« Reply #1 on: May 11, 2022, 06:54:31 pm »
Hi!
What you want is called a daemon

Read this:

https://wiki.lazarus.freepascal.org/Daemons_and_Services

Winni

abdoun.brahim

  • New member
  • *
  • Posts: 9
Re: [Linux] Program that runs in the background
« Reply #2 on: May 11, 2022, 07:09:37 pm »
Hello
Thank you very much I will look at the links.
Thank you

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: [Linux] Program that runs in the background
« Reply #3 on: May 11, 2022, 10:43:25 pm »
In addition to what Winni's said, I'd remind you that Lazarus can be used to develop a non-GUI program that can simply be started with its standard handles defined as /dev/null i.e. like

Code: [Select]
./something >/dev/null 2>&1 &

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

dbannon

  • Hero Member
  • *****
  • Posts: 2786
    • tomboy-ng, a rewrite of the classic Tomboy
Re: [Linux] Program that runs in the background
« Reply #4 on: May 12, 2022, 04:49:29 am »
Code: [Select]
./something >/dev/null 2>&1 &

Code: Pascal  [Select][+][-]
  1. nohup ./something

Is my preferred means, it disconnects the current terminal so closing that terminal does not shut down the app, it redirects std out to a file called 'nohup'. For all intents and purposes, its a daemon.

But you could also look at https://wiki.freepascal.org/Daemons_and_Services for a more structured approach.

Davo

Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: [Linux] Program that runs in the background
« Reply #5 on: May 12, 2022, 10:31:26 am »
I generally advise against using a LazDaemon application on Linux, because it is designed around the Windows API structure for services, which is rather complicated. Like this whole putting your functionatlity in a worker thread that is then signalised through some event methods comes from the way the Windows handles Services.
When you are not targeting Windows, this is all overhead that you do not need, because Daemons on Linux are really easy, because they are just console applications (in fact on Linux every application is a console application, the idea that there are different types of applications is a Windows only concepts).

So to create a daemon for linux is really easy:
Step 1: Create and debug your application as console application
Step 2: Run it in the background

To run an application in the background a few things where already mentioned. Here is some further information.
To run an application from your shell in the background, you need to add an & after the command:
Code: Bash  [Select][+][-]
  1. $> ./myapplication &
There you have two Problems, the first one is that your console output is still bound to the terminal you started your program in, so if you close it and your program tries to do a WriteLn, it will get a broken pipe error, and this probably crashes your application. So you need to handle the output.
If you want to log the output, you can just write it into a file:
Code: Bash  [Select][+][-]
  1. $> ./myapplication > logfile.txt 2>&1 &
The 2>&1 pipes the stderr over the same output as stdout, if you want different logs:
Code: Bash  [Select][+][-]
  1. $> ./myapplication > output.log 2> error.log &
If you want to have it a bit nicer with timestamps, you can also add them through bash:
Code: Bash  [Select][+][-]
  1. $> ./myapplication 2>&1 | ts > log.txt &
but this limits a bit your abilities (e.g. creating a seperate log for stderr, or taking the PID, which I will come to later), so maybe its better to timestamp within your application, e.g. by using a logging library
You can also completely ignore the output by piping it to /dev/null
Code: Bash  [Select][+][-]
  1. $> ./myapplication > /dev/null 2>&1 &

The next problem is that when the shell that opend your program closes, your progrem gets the HUP signal sent, the default action is to close the program. There are two options to avoid this, either start your program via nohup, which basically just catches this signal and ignores it, and everything else is just passed through to your application:
Code: Bash  [Select][+][-]
  1. $> nohup ./myapplication > log.txt 2>&1 &

This is very basic to start a program in the background from your shell. You might want to find that program again later, in which case you might want to save the pid:
Code: Bash  [Select][+][-]
  1. $> ./myapplication > /dev/null 2>&1 &
  2. $> PID=$!
which you can then store locally, e.g. to kill the process later:
Code: Bash  [Select][+][-]
  1. $> ./myapplication > /dev/null 2>&1 &
  2. $> PID=$!
  3. $> echo $PID > myapp.pid
  4. # Killing the process later
  5. $> PID=$(<myapp.pid)
  6. $> kill $PID
So you could just create two simple bash scripts, runService.sh:
Code: Bash  [Select][+][-]
  1. #!/bin/bash
  2. set -e
  3. nohup ./myapplication > output.log 2> error.log &
  4. echo $! > myapplication.pid
and stopService.sh:
Code: Bash  [Select][+][-]
  1. #!/bin/bash
  2. set -e
  3. PID=$(<myapplication.pid)
  4. kill $PID
and voiala you can use these scripts for any console application to turn it into a servcie.
And I think it should be very obvious why I think that these two twoliner bash scripts are much more easy to use than to create a Deamon application as described in the wiki. So for Linux I see absolutely no reason to use the LazDaemon package.

If you want them a bit nicer you can also add some error checking:
Code: Bash  [Select][+][-]
  1. #!/bin/bash
  2. set -e
  3. if [ -f myapplication.pid ]; then
  4.   echo Service already started... please stop first or delete myapplication.pid if the service is not running
  5.   exit
  6. fi
  7. nohup ./myapplication > output.log 2> error.log &
  8. echo $! > myapplication.pid
and stopService.sh:
Code: Bash  [Select][+][-]
  1. #!/bin/bash
  2. set -e
  3. if [ ! -f myapplication.pid ]; then
  4.   echo Service is not running
  5.   exit
  6. fi
  7. PID=$(<myapplication.pid)
  8. kill $PID

Lastly, an alternative that I personally find better than this, is to simply execute the app on a virtual terminal. This is possible via screen or tmux.
You can just open a screen or tmux session, start your console application in there, and then detach from it. In tmux you simply enter the command tmux, then you get a new shell where you call your program (normally, non of this nohub or logging stuff from above) and then you press ctrl followed by ctrl + d to detach.
Your program now runs in a tmux session. When you want to revisit it, simply type "tmux attach" and you are back in the session. There you can see at all the output your program has generated, and you can even provide input (i.e. use readline and co). And later simply detach again to let it run in the background.

Thats in my opinion the best way to run applications in the background, if they do not have to be started automatically boot. If this is the case, you should simply use the scripts shown earlier and put them into an init script, systemd configuration, cronjob, xinit script or whatever you want to use to run a program on boot
« Last Edit: May 12, 2022, 10:40:08 am by Warfley »

abdoun.brahim

  • New member
  • *
  • Posts: 9
Re: [Linux] Program that runs in the background
« Reply #6 on: May 12, 2022, 07:18:29 pm »
Hello
Thank you very much
I found this code I tested:
Code: Pascal  [Select][+][-]
  1. program TimeLogger;
  2. {$APPTYPE CONSOLE}
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6. {$IFDEF UNIX}{$IFDEF UseCThreads}
  7. cthreads,
  8. {$ENDIF}{$ENDIF}
  9. Classes  , sysutils ,baseunix
  10. { you can add units after this };
  11.  
  12. var
  13. TextF: TextFile;
  14. begin
  15. try
  16.   if fpfork()<>0 then begin
  17.      exit;
  18.   end;
  19. repeat
  20. AssignFile(TextF, 'log.txt');
  21. if FileExists('log.txt') then
  22. Append(TextF)
  23. else
  24. Rewrite(TextF);
  25.  
  26. Writeln(TextF, DateTimeToStr(Now));
  27.  
  28. CloseFile(TextF);
  29. Sleep(10000);
  30.  
  31. until false;
  32. except
  33.    on e:exception do
  34.    Writeln(TextF, DateTimeToStr(Now)+': erreur:'+e.message);
  35. end;
  36. end.
  37.  
« Last Edit: May 12, 2022, 07:27:44 pm by abdoun.brahim »

dbannon

  • Hero Member
  • *****
  • Posts: 2786
    • tomboy-ng, a rewrite of the classic Tomboy
Re: [Linux] Program that runs in the background
« Reply #7 on: May 13, 2022, 06:12:35 am »
yes Abdoun, that will work but if you read the responses you see here, you would realise that most of it is unnecessary. And unnecessary code is bad code.

Without testing -
Code: Pascal  [Select][+][-]
  1. program TimeLogger;
  2. {$APPTYPE CONSOLE}
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6. {$IFDEF UNIX}{$IFDEF UseCThreads}
  7. cthreads,
  8. {$ENDIF}{$ENDIF}
  9. Classes  , sysutils ,baseunix
  10. { you can add units after this };
  11.  
  12. begin
  13.     repeat
  14.         Writeln(DateTimeToStr(Now));
  15.         Sleep(10000);
  16.     until false;
  17. end.

Start it with nohup command and you will find your datestamp lines in the file 'nohup' or read Warfley's means of directing it to a specific file.

D


Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: [Linux] Program that runs in the background
« Reply #8 on: May 13, 2022, 09:32:26 am »
It's not just that this is uneccessary code, it also makes debugging of this application impossible. You are just going to make your life harder with this.

Just create a normal command line application that is easy to create and debug, and then execute it in the background as described above

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: [Linux] Program that runs in the background
« Reply #9 on: May 13, 2022, 09:52:13 am »
It's not just that this is uneccessary code, it also makes debugging of this application impossible. You are just going to make your life harder with this.

Just create a normal command line application that is easy to create and debug, and then execute it in the background as described above

I strongly agree, but it's worth noting that the fork() technique is a transcription of legacy C code from some unspecified source (I hope it wasn't the FPC wiki).

The result is, by absolutely any standards, an unacceptable hodgepodge: on the one hand it uses traditional C/unix "lean and mean" fork(), on the other it introduces exception handling and a textfile which are very much "non-C".

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

abdoun.brahim

  • New member
  • *
  • Posts: 9
Re: [Linux] Program that runs in the background
« Reply #10 on: May 13, 2022, 07:21:06 pm »
Thank you very much for your help it's true it's useless to use fpfork I will use :
Code: Pascal  [Select][+][-]
  1. nohup ./myapplication > output.log 2> error.log &
Thank you

 

TinyPortal © 2005-2018