Starting and stopping a program from a shell script












0















This is probably a simple question but I haven't found the answer anywhere.



I want to start a program from a shell script, and then close it from the shell script a little later.



Once the program loads, the script hangs because the focus is now on the opened program.



How do I return the focus to the script?










share|improve this question























  • It sounds like you want to return control to the script - rather than "focus" - if that's the case, then it should be a matter of placing the program in the shell's background. See for example How to start a GUI application from the terminal and return immediately?

    – steeldriver
    Mar 10 at 1:07













  • @steeldriver Anything you want to add to my answer ?

    – Sergiy Kolodyazhnyy
    Mar 10 at 5:28











  • For some reason, no matter how I try, putting the ampersand after the command does not free up the terminal for me. I've seen that explanation many times, but it's just not working. Thank you for the suggestion!

    – ubuntu_is_cool
    Mar 10 at 16:16
















0















This is probably a simple question but I haven't found the answer anywhere.



I want to start a program from a shell script, and then close it from the shell script a little later.



Once the program loads, the script hangs because the focus is now on the opened program.



How do I return the focus to the script?










share|improve this question























  • It sounds like you want to return control to the script - rather than "focus" - if that's the case, then it should be a matter of placing the program in the shell's background. See for example How to start a GUI application from the terminal and return immediately?

    – steeldriver
    Mar 10 at 1:07













  • @steeldriver Anything you want to add to my answer ?

    – Sergiy Kolodyazhnyy
    Mar 10 at 5:28











  • For some reason, no matter how I try, putting the ampersand after the command does not free up the terminal for me. I've seen that explanation many times, but it's just not working. Thank you for the suggestion!

    – ubuntu_is_cool
    Mar 10 at 16:16














0












0








0








This is probably a simple question but I haven't found the answer anywhere.



I want to start a program from a shell script, and then close it from the shell script a little later.



Once the program loads, the script hangs because the focus is now on the opened program.



How do I return the focus to the script?










share|improve this question














This is probably a simple question but I haven't found the answer anywhere.



I want to start a program from a shell script, and then close it from the shell script a little later.



Once the program loads, the script hangs because the focus is now on the opened program.



How do I return the focus to the script?







command-line gnome scripts






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 10 at 0:48









ubuntu_is_coolubuntu_is_cool

214




214













  • It sounds like you want to return control to the script - rather than "focus" - if that's the case, then it should be a matter of placing the program in the shell's background. See for example How to start a GUI application from the terminal and return immediately?

    – steeldriver
    Mar 10 at 1:07













  • @steeldriver Anything you want to add to my answer ?

    – Sergiy Kolodyazhnyy
    Mar 10 at 5:28











  • For some reason, no matter how I try, putting the ampersand after the command does not free up the terminal for me. I've seen that explanation many times, but it's just not working. Thank you for the suggestion!

    – ubuntu_is_cool
    Mar 10 at 16:16



















  • It sounds like you want to return control to the script - rather than "focus" - if that's the case, then it should be a matter of placing the program in the shell's background. See for example How to start a GUI application from the terminal and return immediately?

    – steeldriver
    Mar 10 at 1:07













  • @steeldriver Anything you want to add to my answer ?

    – Sergiy Kolodyazhnyy
    Mar 10 at 5:28











  • For some reason, no matter how I try, putting the ampersand after the command does not free up the terminal for me. I've seen that explanation many times, but it's just not working. Thank you for the suggestion!

    – ubuntu_is_cool
    Mar 10 at 16:16

















It sounds like you want to return control to the script - rather than "focus" - if that's the case, then it should be a matter of placing the program in the shell's background. See for example How to start a GUI application from the terminal and return immediately?

– steeldriver
Mar 10 at 1:07







It sounds like you want to return control to the script - rather than "focus" - if that's the case, then it should be a matter of placing the program in the shell's background. See for example How to start a GUI application from the terminal and return immediately?

– steeldriver
Mar 10 at 1:07















@steeldriver Anything you want to add to my answer ?

– Sergiy Kolodyazhnyy
Mar 10 at 5:28





@steeldriver Anything you want to add to my answer ?

– Sergiy Kolodyazhnyy
Mar 10 at 5:28













For some reason, no matter how I try, putting the ampersand after the command does not free up the terminal for me. I've seen that explanation many times, but it's just not working. Thank you for the suggestion!

– ubuntu_is_cool
Mar 10 at 16:16





For some reason, no matter how I try, putting the ampersand after the command does not free up the terminal for me. I've seen that explanation many times, but it's just not working. Thank you for the suggestion!

– ubuntu_is_cool
Mar 10 at 16:16










1 Answer
1






active

oldest

votes


















1















I want to start a program from a shell script, and then close it from the shell script a little later.




Scripts by nature are sequential, and any command executed in the script that is not built in, requires creating separate process and wait for that process to return control to the script. There's a few other intricate details, but that's the basic gist of how shell scripts work.



Now, what you're asking is to have a script start a process and use the same script to close the process. That means the command has to be independent from the script - separate process - and know what is that process somehow. Without going too much into details of multiple ways of how this can be done, most practical way is to create a .pid file for the command.



For instance, here's a script that could do something like this:



#!/bin/sh

pid_file_exists()[ -f "$1" ]
pid_file='/tmp/mycommand.pid'

# Check if file exists, which may mean the process exists
if pid_file_exists "$pid_file" ; then
pid=$(cat "$pid_file" )
# Replace script with kill command. This will prevent going
# further in the script.
rm "$pid_file"
exec kill $pid
fi

# Save script's PID
echo $$ > "$pid_file"
# Replace script process with zenity, PID now
# is saved and we know it belongs to this command, not script
exec zenity --info "THIS IS A TEST"


If you start the script in one terminal tab you will see the popup created by zenity utility. If you run the script in another tab - it will kill that popup. Now you will notice that the script retains control of the terminal in first tab. That's simply how the shell processes work. So in case you want to do that from the same terminal you might want to use either nohup or setsid command to detach the script when starting the desired app. For example, to start use



# &>/dev/null hides all output
setsid ./controller_script.sh &>/dev/null


and to close you can just do



./controller_script.sh


Note also that assumption here is that you want to control the app via script only. If the app that you want to control has exited already (closed by GUI button or by another process), you'll get an error but that's it - no harm done from the error. Now,if that PID is owned by another process already - that could be a problem, so if you're going to implement something truly portable you might also add checks for whether the process really belongs to the app you intended, for example via checking /proc/$pid/cmdline file.






share|improve this answer























    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "89"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1124424%2fstarting-and-stopping-a-program-from-a-shell-script%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1















    I want to start a program from a shell script, and then close it from the shell script a little later.




    Scripts by nature are sequential, and any command executed in the script that is not built in, requires creating separate process and wait for that process to return control to the script. There's a few other intricate details, but that's the basic gist of how shell scripts work.



    Now, what you're asking is to have a script start a process and use the same script to close the process. That means the command has to be independent from the script - separate process - and know what is that process somehow. Without going too much into details of multiple ways of how this can be done, most practical way is to create a .pid file for the command.



    For instance, here's a script that could do something like this:



    #!/bin/sh

    pid_file_exists()[ -f "$1" ]
    pid_file='/tmp/mycommand.pid'

    # Check if file exists, which may mean the process exists
    if pid_file_exists "$pid_file" ; then
    pid=$(cat "$pid_file" )
    # Replace script with kill command. This will prevent going
    # further in the script.
    rm "$pid_file"
    exec kill $pid
    fi

    # Save script's PID
    echo $$ > "$pid_file"
    # Replace script process with zenity, PID now
    # is saved and we know it belongs to this command, not script
    exec zenity --info "THIS IS A TEST"


    If you start the script in one terminal tab you will see the popup created by zenity utility. If you run the script in another tab - it will kill that popup. Now you will notice that the script retains control of the terminal in first tab. That's simply how the shell processes work. So in case you want to do that from the same terminal you might want to use either nohup or setsid command to detach the script when starting the desired app. For example, to start use



    # &>/dev/null hides all output
    setsid ./controller_script.sh &>/dev/null


    and to close you can just do



    ./controller_script.sh


    Note also that assumption here is that you want to control the app via script only. If the app that you want to control has exited already (closed by GUI button or by another process), you'll get an error but that's it - no harm done from the error. Now,if that PID is owned by another process already - that could be a problem, so if you're going to implement something truly portable you might also add checks for whether the process really belongs to the app you intended, for example via checking /proc/$pid/cmdline file.






    share|improve this answer




























      1















      I want to start a program from a shell script, and then close it from the shell script a little later.




      Scripts by nature are sequential, and any command executed in the script that is not built in, requires creating separate process and wait for that process to return control to the script. There's a few other intricate details, but that's the basic gist of how shell scripts work.



      Now, what you're asking is to have a script start a process and use the same script to close the process. That means the command has to be independent from the script - separate process - and know what is that process somehow. Without going too much into details of multiple ways of how this can be done, most practical way is to create a .pid file for the command.



      For instance, here's a script that could do something like this:



      #!/bin/sh

      pid_file_exists()[ -f "$1" ]
      pid_file='/tmp/mycommand.pid'

      # Check if file exists, which may mean the process exists
      if pid_file_exists "$pid_file" ; then
      pid=$(cat "$pid_file" )
      # Replace script with kill command. This will prevent going
      # further in the script.
      rm "$pid_file"
      exec kill $pid
      fi

      # Save script's PID
      echo $$ > "$pid_file"
      # Replace script process with zenity, PID now
      # is saved and we know it belongs to this command, not script
      exec zenity --info "THIS IS A TEST"


      If you start the script in one terminal tab you will see the popup created by zenity utility. If you run the script in another tab - it will kill that popup. Now you will notice that the script retains control of the terminal in first tab. That's simply how the shell processes work. So in case you want to do that from the same terminal you might want to use either nohup or setsid command to detach the script when starting the desired app. For example, to start use



      # &>/dev/null hides all output
      setsid ./controller_script.sh &>/dev/null


      and to close you can just do



      ./controller_script.sh


      Note also that assumption here is that you want to control the app via script only. If the app that you want to control has exited already (closed by GUI button or by another process), you'll get an error but that's it - no harm done from the error. Now,if that PID is owned by another process already - that could be a problem, so if you're going to implement something truly portable you might also add checks for whether the process really belongs to the app you intended, for example via checking /proc/$pid/cmdline file.






      share|improve this answer


























        1












        1








        1








        I want to start a program from a shell script, and then close it from the shell script a little later.




        Scripts by nature are sequential, and any command executed in the script that is not built in, requires creating separate process and wait for that process to return control to the script. There's a few other intricate details, but that's the basic gist of how shell scripts work.



        Now, what you're asking is to have a script start a process and use the same script to close the process. That means the command has to be independent from the script - separate process - and know what is that process somehow. Without going too much into details of multiple ways of how this can be done, most practical way is to create a .pid file for the command.



        For instance, here's a script that could do something like this:



        #!/bin/sh

        pid_file_exists()[ -f "$1" ]
        pid_file='/tmp/mycommand.pid'

        # Check if file exists, which may mean the process exists
        if pid_file_exists "$pid_file" ; then
        pid=$(cat "$pid_file" )
        # Replace script with kill command. This will prevent going
        # further in the script.
        rm "$pid_file"
        exec kill $pid
        fi

        # Save script's PID
        echo $$ > "$pid_file"
        # Replace script process with zenity, PID now
        # is saved and we know it belongs to this command, not script
        exec zenity --info "THIS IS A TEST"


        If you start the script in one terminal tab you will see the popup created by zenity utility. If you run the script in another tab - it will kill that popup. Now you will notice that the script retains control of the terminal in first tab. That's simply how the shell processes work. So in case you want to do that from the same terminal you might want to use either nohup or setsid command to detach the script when starting the desired app. For example, to start use



        # &>/dev/null hides all output
        setsid ./controller_script.sh &>/dev/null


        and to close you can just do



        ./controller_script.sh


        Note also that assumption here is that you want to control the app via script only. If the app that you want to control has exited already (closed by GUI button or by another process), you'll get an error but that's it - no harm done from the error. Now,if that PID is owned by another process already - that could be a problem, so if you're going to implement something truly portable you might also add checks for whether the process really belongs to the app you intended, for example via checking /proc/$pid/cmdline file.






        share|improve this answer














        I want to start a program from a shell script, and then close it from the shell script a little later.




        Scripts by nature are sequential, and any command executed in the script that is not built in, requires creating separate process and wait for that process to return control to the script. There's a few other intricate details, but that's the basic gist of how shell scripts work.



        Now, what you're asking is to have a script start a process and use the same script to close the process. That means the command has to be independent from the script - separate process - and know what is that process somehow. Without going too much into details of multiple ways of how this can be done, most practical way is to create a .pid file for the command.



        For instance, here's a script that could do something like this:



        #!/bin/sh

        pid_file_exists()[ -f "$1" ]
        pid_file='/tmp/mycommand.pid'

        # Check if file exists, which may mean the process exists
        if pid_file_exists "$pid_file" ; then
        pid=$(cat "$pid_file" )
        # Replace script with kill command. This will prevent going
        # further in the script.
        rm "$pid_file"
        exec kill $pid
        fi

        # Save script's PID
        echo $$ > "$pid_file"
        # Replace script process with zenity, PID now
        # is saved and we know it belongs to this command, not script
        exec zenity --info "THIS IS A TEST"


        If you start the script in one terminal tab you will see the popup created by zenity utility. If you run the script in another tab - it will kill that popup. Now you will notice that the script retains control of the terminal in first tab. That's simply how the shell processes work. So in case you want to do that from the same terminal you might want to use either nohup or setsid command to detach the script when starting the desired app. For example, to start use



        # &>/dev/null hides all output
        setsid ./controller_script.sh &>/dev/null


        and to close you can just do



        ./controller_script.sh


        Note also that assumption here is that you want to control the app via script only. If the app that you want to control has exited already (closed by GUI button or by another process), you'll get an error but that's it - no harm done from the error. Now,if that PID is owned by another process already - that could be a problem, so if you're going to implement something truly portable you might also add checks for whether the process really belongs to the app you intended, for example via checking /proc/$pid/cmdline file.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 10 at 5:12









        Sergiy KolodyazhnyySergiy Kolodyazhnyy

        74.1k9155324




        74.1k9155324






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Ask Ubuntu!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1124424%2fstarting-and-stopping-a-program-from-a-shell-script%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            How did Captain America manage to do this?

            迪纳利

            南乌拉尔铁路局