Starting and stopping a program from a shell script
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
add a comment |
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
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
add a comment |
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
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
command-line gnome scripts
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered Mar 10 at 5:12
Sergiy KolodyazhnyySergiy Kolodyazhnyy
74.1k9155324
74.1k9155324
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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