Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Execute .sh script in a way that it keeps running after Qt programm has quit
QtWS25 Last Chance

Execute .sh script in a way that it keeps running after Qt programm has quit

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
14 Posts 5 Posters 7.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Markus Ippy
    wrote on 1 Dec 2017, 06:36 last edited by A Former User 12 Jan 2017, 13:33
    #1

    I have a raspberry pi programm written wit QT5.8 opensource.
    I wanted to give the user a possibility to update the program from source directly from the program itself.
    The program is installed in "$/opt/PowerTune" the source code resides in "/home/pi/PowerTune"
    i have written a sh script to update the program :

    //Contents of the script update.sh
    cd /home/pi/PowerTune
    git pull
    pkill -f PowerTuneQMLGui //Close my program before removing the install directory
    sudo rm -r /opt/PowerTune //remove the old install directory
    sudo mkdir /opt/PowerTune
    sudo chown /opt/PowerTune
    cd /opt/PowerTune
    qmake /home/pi/PowerTune/PowerTuneQMLGui.pro
    make
    sudo reboot now
    //End Script

    I execute my script from within c++

    void Serial::update()
    {
    QProcess process;
    process.startDetached("/bin/sh", QStringList()<< "/home/pi/update.sh");
    qDebug() << "Update PowerTune.";
    }

    My Problem now is that i oviously kill my program before deleting the install directory .
    Is there any way i can start the execute the script that it keeps running after i kill my qt programm ?

    A J 2 Replies Last reply 1 Dec 2017, 08:01
    0
    • M Markus Ippy
      1 Dec 2017, 06:36

      I have a raspberry pi programm written wit QT5.8 opensource.
      I wanted to give the user a possibility to update the program from source directly from the program itself.
      The program is installed in "$/opt/PowerTune" the source code resides in "/home/pi/PowerTune"
      i have written a sh script to update the program :

      //Contents of the script update.sh
      cd /home/pi/PowerTune
      git pull
      pkill -f PowerTuneQMLGui //Close my program before removing the install directory
      sudo rm -r /opt/PowerTune //remove the old install directory
      sudo mkdir /opt/PowerTune
      sudo chown /opt/PowerTune
      cd /opt/PowerTune
      qmake /home/pi/PowerTune/PowerTuneQMLGui.pro
      make
      sudo reboot now
      //End Script

      I execute my script from within c++

      void Serial::update()
      {
      QProcess process;
      process.startDetached("/bin/sh", QStringList()<< "/home/pi/update.sh");
      qDebug() << "Update PowerTune.";
      }

      My Problem now is that i oviously kill my program before deleting the install directory .
      Is there any way i can start the execute the script that it keeps running after i kill my qt programm ?

      A Offline
      A Offline
      aha_1980
      Lifetime Qt Champion
      wrote on 1 Dec 2017, 08:01 last edited by
      #2

      @Markus-Ippy Maybe not the answer you expected, but have you thougt about running the script on boot before your program runs?

      you would put the update files at a defined dir and pick them up from your script if they exist. otherwise just start your program normally.

      Qt has to stay free or it will die.

      1 Reply Last reply
      1
      • M Offline
        M Offline
        Markus Ippy
        wrote on 1 Dec 2017, 08:05 last edited by
        #3

        @aha_1980 said in execute .sh script in a way that it keeps running after qt programm has quit:

        would put the update files at a defined dir and pick them up from your script if they exist. otherwise just start your program normally.

        I haven't thought about that. that is actually not a bad idea. Nevertheless it would be interesting to know if i can start a script from QT that stays alive even after the QT programm gets closed .

        A J 2 Replies Last reply 1 Dec 2017, 08:40
        0
        • M Markus Ippy
          1 Dec 2017, 08:05

          @aha_1980 said in execute .sh script in a way that it keeps running after qt programm has quit:

          would put the update files at a defined dir and pick them up from your script if they exist. otherwise just start your program normally.

          I haven't thought about that. that is actually not a bad idea. Nevertheless it would be interesting to know if i can start a script from QT that stays alive even after the QT programm gets closed .

          A Offline
          A Offline
          aha_1980
          Lifetime Qt Champion
          wrote on 1 Dec 2017, 08:40 last edited by
          #4

          @Markus-Ippy reading the docs of startDetached it should already work. have you tried exiting your Qt program the 'normal' way i.e. not by killing it?

          Qt has to stay free or it will die.

          M 1 Reply Last reply 1 Dec 2017, 09:22
          1
          • A aha_1980
            1 Dec 2017, 08:40

            @Markus-Ippy reading the docs of startDetached it should already work. have you tried exiting your Qt program the 'normal' way i.e. not by killing it?

            M Offline
            M Offline
            Markus Ippy
            wrote on 1 Dec 2017, 09:22 last edited by
            #5

            @aha_1980 I haven't tried via Qt.quit() yet . i will try that when i come home tonight and let you know

            1 Reply Last reply
            0
            • M Markus Ippy
              1 Dec 2017, 06:36

              I have a raspberry pi programm written wit QT5.8 opensource.
              I wanted to give the user a possibility to update the program from source directly from the program itself.
              The program is installed in "$/opt/PowerTune" the source code resides in "/home/pi/PowerTune"
              i have written a sh script to update the program :

              //Contents of the script update.sh
              cd /home/pi/PowerTune
              git pull
              pkill -f PowerTuneQMLGui //Close my program before removing the install directory
              sudo rm -r /opt/PowerTune //remove the old install directory
              sudo mkdir /opt/PowerTune
              sudo chown /opt/PowerTune
              cd /opt/PowerTune
              qmake /home/pi/PowerTune/PowerTuneQMLGui.pro
              make
              sudo reboot now
              //End Script

              I execute my script from within c++

              void Serial::update()
              {
              QProcess process;
              process.startDetached("/bin/sh", QStringList()<< "/home/pi/update.sh");
              qDebug() << "Update PowerTune.";
              }

              My Problem now is that i oviously kill my program before deleting the install directory .
              Is there any way i can start the execute the script that it keeps running after i kill my qt programm ?

              J Offline
              J Offline
              JonB
              wrote on 1 Dec 2017, 09:35 last edited by
              #6

              @Markus-Ippy
              Firstly, in your script, which I assume you have copied & pasted here:

              sudo chown /opt/PowerTune

              should give:

              jon@ubuntu:~$ sudo chown file
              chown: missing operand after ‘file’
              Try 'chown --help' for more information.
              

              ?

              Now to summarise your situation:

              1. You run Qt app PowerTuneQMLGui which launches script via QProcess::startDetached().
              2. Script executes pkill -f PowerTuneQMLGui, killing your app.
              3. You're finding that killing the app immediately also kills your script.

              Right?

              http://doc.qt.io/qt-5/qprocess.html#startDetached claims:

              Unix: The started process will run in its own session and act like a daemon.

              We don't know what code startDetached() uses under Linux, but I agree that explanation implies to me that the script should not itself get terminated....

              Let's be clear about the behaviour you are actually seeing. You say:

              My Problem now is that i oviously kill my program before deleting the install directory .

              Deleting the install directory is the least of your problems. If you are right your script gets killed at the pkill -f PowerTuneQMLGui //Close my program before removing the install directory line. In that case it does not proceed to any further line at all, so it never does the qmake or reboot at all. Is that what you experience?

              M 1 Reply Last reply 1 Dec 2017, 11:01
              0
              • J JonB
                1 Dec 2017, 09:35

                @Markus-Ippy
                Firstly, in your script, which I assume you have copied & pasted here:

                sudo chown /opt/PowerTune

                should give:

                jon@ubuntu:~$ sudo chown file
                chown: missing operand after ‘file’
                Try 'chown --help' for more information.
                

                ?

                Now to summarise your situation:

                1. You run Qt app PowerTuneQMLGui which launches script via QProcess::startDetached().
                2. Script executes pkill -f PowerTuneQMLGui, killing your app.
                3. You're finding that killing the app immediately also kills your script.

                Right?

                http://doc.qt.io/qt-5/qprocess.html#startDetached claims:

                Unix: The started process will run in its own session and act like a daemon.

                We don't know what code startDetached() uses under Linux, but I agree that explanation implies to me that the script should not itself get terminated....

                Let's be clear about the behaviour you are actually seeing. You say:

                My Problem now is that i oviously kill my program before deleting the install directory .

                Deleting the install directory is the least of your problems. If you are right your script gets killed at the pkill -f PowerTuneQMLGui //Close my program before removing the install directory line. In that case it does not proceed to any further line at all, so it never does the qmake or reboot at all. Is that what you experience?

                M Offline
                M Offline
                Markus Ippy
                wrote on 1 Dec 2017, 11:01 last edited by
                #7

                Sorry i just typed what i have in the script not copied and pasted it
                in the script i use :
                $ sudo chown pi:pi /opt/PowerTune

                The script itself works properly when executed from commandline . my program is running in a car so its inconvenient to have a mouse and keyboard , hence my try to execute the script from my program.

                As for what i am experiencing you are spot on
                pkill -f PowerTuneQMLGui also stops the script and i just end up on the command line without the delete / qmake / reboot

                E 1 Reply Last reply 1 Dec 2017, 11:26
                0
                • M Markus Ippy
                  1 Dec 2017, 11:01

                  Sorry i just typed what i have in the script not copied and pasted it
                  in the script i use :
                  $ sudo chown pi:pi /opt/PowerTune

                  The script itself works properly when executed from commandline . my program is running in a car so its inconvenient to have a mouse and keyboard , hence my try to execute the script from my program.

                  As for what i am experiencing you are spot on
                  pkill -f PowerTuneQMLGui also stops the script and i just end up on the command line without the delete / qmake / reboot

                  E Offline
                  E Offline
                  ErikR
                  wrote on 1 Dec 2017, 11:26 last edited by
                  #8

                  @Markus-Ippy

                  Hi,
                  What if you add a "shebang" in the script-file and makes it executable;

                  First row of script:

                  #!/bin/sh
                  

                  Then start the script as any other program and not as an argument to /bin/sh.

                  process.startDetached(""/home/pi/update.sh");
                  

                  (I have not verified that startDetached can operate without the second argument)

                  A 1 Reply Last reply 1 Dec 2017, 11:37
                  0
                  • E ErikR
                    1 Dec 2017, 11:26

                    @Markus-Ippy

                    Hi,
                    What if you add a "shebang" in the script-file and makes it executable;

                    First row of script:

                    #!/bin/sh
                    

                    Then start the script as any other program and not as an argument to /bin/sh.

                    process.startDetached(""/home/pi/update.sh");
                    

                    (I have not verified that startDetached can operate without the second argument)

                    A Offline
                    A Offline
                    aha_1980
                    Lifetime Qt Champion
                    wrote on 1 Dec 2017, 11:37 last edited by
                    #9

                    @ErikR that will not make a difference in reality. Hint: the script is still run by the interpreter mentioned in the shebang.

                    Qt has to stay free or it will die.

                    E 1 Reply Last reply 1 Dec 2017, 12:42
                    1
                    • A aha_1980
                      1 Dec 2017, 11:37

                      @ErikR that will not make a difference in reality. Hint: the script is still run by the interpreter mentioned in the shebang.

                      E Offline
                      E Offline
                      ErikR
                      wrote on 1 Dec 2017, 12:42 last edited by
                      #10

                      @aha_1980

                      Well, we can conclude that startDetached does not really start as detached we might expect in this particular case.

                      I would assume that in the first case /bin/sh is started by the Qt application with an argument that happens to be a script-file (there is a lot of options to sh and bash, you might want to look into them).

                      In the second case a recognized executable program is started by the Qt application and the OS will figure out that it shall be interpreted using /bin/sh.

                      It will work the same on high level but might differ on the lower levels and as we are hunting some obscure reason to why startDetached does not actually start detached it might work different.

                      Another thing I have stumbled on is that the file of a started process can be overwritten while the already started process remains intact (well, loading dynamic libraries will not work well). I am not sure how this works on lower levels but when I stumbled on this it looked like the started version of the file was accessible from within the running program while any new process will use the new one. This was on the Solaris 2.6 age and might need to be verified for Linux ;)

                      The implication in this case is the started process will survive the script removing its files and one might consider not to kill the process at all as reboot will do that eventually which will solve the actual problem; successful rebuild and reboot

                      1 Reply Last reply
                      0
                      • ? Offline
                        ? Offline
                        A Former User
                        wrote on 1 Dec 2017, 13:33 last edited by
                        #11

                        @Markus-Ippy said in execute .sh script in a way that it keeps running after qt programm has quit:

                        I wanted to give the user a possibility to update the program from source directly from the program itself.

                        But why? That's the one great thing about Linux distributions, that they all come with a unified install / update mechanism for all parts of the system. Why torture your users with a wacky home-grown updater?

                        1 Reply Last reply
                        1
                        • M Markus Ippy
                          1 Dec 2017, 08:05

                          @aha_1980 said in execute .sh script in a way that it keeps running after qt programm has quit:

                          would put the update files at a defined dir and pick them up from your script if they exist. otherwise just start your program normally.

                          I haven't thought about that. that is actually not a bad idea. Nevertheless it would be interesting to know if i can start a script from QT that stays alive even after the QT programm gets closed .

                          J Offline
                          J Offline
                          JonB
                          wrote on 1 Dec 2017, 15:59 last edited by JonB 12 Jan 2017, 16:00
                          #12

                          @Markus-Ippy
                          Assuming you're still interested in pursuing the reason for this behaviour...

                          As I said, from the Qt docs on startDetached() I would have expected you sub-process not to get killed when the parent Qt app gets killed. I'm certainly interested if you are!

                          To find out what is going on, I would replace the content of your script with something like sleep 60 or similar. Set it off from within your app.

                          Now use ps with options to get all details about both your running app and the sub-process. I think ps -ejH will do it. (You will want to specify other options to reduce the number of processes shown or show more of the command-line to identify what is what, since you're writing scripts I imagine you can figure that.)

                          The column headers are at the top of the output: the first 3 are PID, PGID & SID. That's the ids for the process itself, the Group id & the Session id. What we need to know is whether your parent application and your sub-process child do or do not have same Group and/or Session ids, as this affects who signals delivered to the parent (your app) do or do not also get sent to.

                          If you fancy coming back with that information we would be in a starting position to understand what's going on to produce the behaviour you see!

                          1 Reply Last reply
                          1
                          • E Offline
                            E Offline
                            ErikR
                            wrote on 2 Dec 2017, 12:47 last edited by
                            #13

                            @Markus-Ippy said in Execute .sh script in a way that it keeps running after Qt programm has quit:

                            I managed to get it work by adding a ampersand to the arg-list. Strange that it is needed but well, it made the trick. For non-unix/linux users this is the signal to start a process in the background.

                            The script:

                            #!/bin/bash
                            
                            echo "Test-script started with PID = ${$}" >> log.txt
                            sleep 5
                            echo "Kill and remove the program"  >> log.txt
                            pkill -f script-restart-test  >> log.txt
                            rm script-restart-test  >> log.txt
                            echo "Done killing, sleep" >> log.txt 
                            sleep 5
                            echo "Terminating" >> log.txt
                            
                            

                            The reason I use a logfile (wich I tail -f in another window) is that output is lost when the parent is killed and there are no indication beside ps to verify that the script-process is still alive. In general printouts from background processes may cause problems from time to time, better to log to a file.

                            The Qt C++ code cut from a public slot triggered by a button in a newly generated application:

                            void MainWindow::runScript()
                            {
                                bool bStatus = false;
                            
                                QStringList args;
                                qint64      pid = 0;
                            
                                args << "&";
                                bStatus = QProcess::startDetached("./testscript.sh", args, ".", &pid);
                            
                                qDebug() << "Started process detached";
                                qDebug() << "got PID = " << pid;
                                qDebug() << "and status = " << bStatus;
                            
                            }
                            

                            I observed that the child process (script) started got PID 1 as parent process (unsing ps -def).

                            $ ps -def | grep script
                            ....     24268  5572  1 13:40 ?        00:00:00 /home/..../script-restart-test
                            ....     24273     1  0 13:40 ?        00:00:00 /bin/bash ./testscript.sh &
                            ....     24276 22779  0 13:40 pts/6    00:00:00 grep --colour=auto script
                            
                            $ ps -def | grep script
                            ....     24273     1  0 13:40 ?        00:00:00 /bin/bash ./testscript.sh &
                            ....     24282 22779  0 13:41 pts/6    00:00:00 grep --colour=auto script
                            

                            Regards,
                            Erik

                            J 1 Reply Last reply 4 Dec 2017, 09:22
                            1
                            • E ErikR
                              2 Dec 2017, 12:47

                              @Markus-Ippy said in Execute .sh script in a way that it keeps running after Qt programm has quit:

                              I managed to get it work by adding a ampersand to the arg-list. Strange that it is needed but well, it made the trick. For non-unix/linux users this is the signal to start a process in the background.

                              The script:

                              #!/bin/bash
                              
                              echo "Test-script started with PID = ${$}" >> log.txt
                              sleep 5
                              echo "Kill and remove the program"  >> log.txt
                              pkill -f script-restart-test  >> log.txt
                              rm script-restart-test  >> log.txt
                              echo "Done killing, sleep" >> log.txt 
                              sleep 5
                              echo "Terminating" >> log.txt
                              
                              

                              The reason I use a logfile (wich I tail -f in another window) is that output is lost when the parent is killed and there are no indication beside ps to verify that the script-process is still alive. In general printouts from background processes may cause problems from time to time, better to log to a file.

                              The Qt C++ code cut from a public slot triggered by a button in a newly generated application:

                              void MainWindow::runScript()
                              {
                                  bool bStatus = false;
                              
                                  QStringList args;
                                  qint64      pid = 0;
                              
                                  args << "&";
                                  bStatus = QProcess::startDetached("./testscript.sh", args, ".", &pid);
                              
                                  qDebug() << "Started process detached";
                                  qDebug() << "got PID = " << pid;
                                  qDebug() << "and status = " << bStatus;
                              
                              }
                              

                              I observed that the child process (script) started got PID 1 as parent process (unsing ps -def).

                              $ ps -def | grep script
                              ....     24268  5572  1 13:40 ?        00:00:00 /home/..../script-restart-test
                              ....     24273     1  0 13:40 ?        00:00:00 /bin/bash ./testscript.sh &
                              ....     24276 22779  0 13:40 pts/6    00:00:00 grep --colour=auto script
                              
                              $ ps -def | grep script
                              ....     24273     1  0 13:40 ?        00:00:00 /bin/bash ./testscript.sh &
                              ....     24282 22779  0 13:41 pts/6    00:00:00 grep --colour=auto script
                              

                              Regards,
                              Erik

                              J Offline
                              J Offline
                              JonB
                              wrote on 4 Dec 2017, 09:22 last edited by JonB 12 Apr 2017, 09:29
                              #14

                              @ErikR
                              When a process has PPID of 1, it has been removed from the parent's process group, and is immune from signals delivered to parent, i.e. just what you wanted.

                              When a shell runs a command with an &, it sets so that the child process has PPID of 1.

                              I still would have expected startDetached() to have done this itself from the docs ("runs it as a daemon process"), but we don't know for sure what the code is. So thanks for your tip.

                              If you want an explanation of "sessions" & "process groups": http://www.informit.com/articles/article.aspx?p=397655&seqNum=6

                              P.S.
                              Since telling you to use ps to find out about running processes, I have now learned that Linux has the /proc pseudo-filing system for processes (didn't used to exist in my old UNIX days!). cattting "files" there reveals all sorts of interesting information about the process!

                              1 Reply Last reply
                              0

                              10/14

                              1 Dec 2017, 12:42

                              • Login

                              • Login or register to search.
                              10 out of 14
                              • First post
                                10/14
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved