linux - signal not passed to multi-command










0














Im trying to understand why signals arent being passed properly under this setup.
Simple test, I have a python script that registers a sigterm handler and prints if it gets it. I have verified this works if i run it and send a TERM.



However, I happen to be running this as a python Subprocess with useShell = True. useShell launches the command with /bin/sh -c ...



If I do this, it actually works as well:



$/bin/sh -c "python ~/tmpcode/signal_test.py" &
[8] 6207
$ kill 6207
signum 15


However, I have scripts that do chained commands, ie /foo/bar.sh; some_other_script.py. Under this scenario, the signal is not passed to the final script:



$ /bin/sh -c "echo foo; python ~/tmpcode/signal_test.py" &
[8] 8015
$ kill 8015


Same thing happens if I try && instead of ;
Im trying to understand whats going on here, and if there is a way to get the signal to chain through.
Side point: The main reason the script is running multi-chain commands is because the first command sets up some environment for the second one to use.



signal_test.py:



import time
import signal
import sys

def handler( signum, frame ):
print( "signum %dn" % signum )
sys.exit(signum)

signal.signal( signal.SIGTERM, handler )
time.sleep(60)









share|improve this question



















  • 1




    That is because Python process will have a different process id.
    – user902384
    Nov 9 '18 at 14:27










  • @user902384 That doesn't explain how signal_test.py gets the signal in the first question.
    – chepner
    Nov 9 '18 at 15:06










  • But in the first example, sh may be optimized to use exec to run the single specified command, meaning 6207 is the Python process. In the second example, sh is instead forking a new process for Python. (If you show the contents of signal_test.py, we could probably suggest how to confirm this hypothesis.)
    – chepner
    Nov 9 '18 at 15:13










  • Might also help to see ps -fu $LOGNAME, and maybe trap.
    – Paul Hodges
    Nov 9 '18 at 15:49







  • 1




    @ByteMe95 How does kill 6207 (which sends SIGTERM to a process) get processed by your script (which only installs a handler for SIGKILL)?
    – chepner
    Nov 10 '18 at 14:29















0














Im trying to understand why signals arent being passed properly under this setup.
Simple test, I have a python script that registers a sigterm handler and prints if it gets it. I have verified this works if i run it and send a TERM.



However, I happen to be running this as a python Subprocess with useShell = True. useShell launches the command with /bin/sh -c ...



If I do this, it actually works as well:



$/bin/sh -c "python ~/tmpcode/signal_test.py" &
[8] 6207
$ kill 6207
signum 15


However, I have scripts that do chained commands, ie /foo/bar.sh; some_other_script.py. Under this scenario, the signal is not passed to the final script:



$ /bin/sh -c "echo foo; python ~/tmpcode/signal_test.py" &
[8] 8015
$ kill 8015


Same thing happens if I try && instead of ;
Im trying to understand whats going on here, and if there is a way to get the signal to chain through.
Side point: The main reason the script is running multi-chain commands is because the first command sets up some environment for the second one to use.



signal_test.py:



import time
import signal
import sys

def handler( signum, frame ):
print( "signum %dn" % signum )
sys.exit(signum)

signal.signal( signal.SIGTERM, handler )
time.sleep(60)









share|improve this question



















  • 1




    That is because Python process will have a different process id.
    – user902384
    Nov 9 '18 at 14:27










  • @user902384 That doesn't explain how signal_test.py gets the signal in the first question.
    – chepner
    Nov 9 '18 at 15:06










  • But in the first example, sh may be optimized to use exec to run the single specified command, meaning 6207 is the Python process. In the second example, sh is instead forking a new process for Python. (If you show the contents of signal_test.py, we could probably suggest how to confirm this hypothesis.)
    – chepner
    Nov 9 '18 at 15:13










  • Might also help to see ps -fu $LOGNAME, and maybe trap.
    – Paul Hodges
    Nov 9 '18 at 15:49







  • 1




    @ByteMe95 How does kill 6207 (which sends SIGTERM to a process) get processed by your script (which only installs a handler for SIGKILL)?
    – chepner
    Nov 10 '18 at 14:29













0












0








0







Im trying to understand why signals arent being passed properly under this setup.
Simple test, I have a python script that registers a sigterm handler and prints if it gets it. I have verified this works if i run it and send a TERM.



However, I happen to be running this as a python Subprocess with useShell = True. useShell launches the command with /bin/sh -c ...



If I do this, it actually works as well:



$/bin/sh -c "python ~/tmpcode/signal_test.py" &
[8] 6207
$ kill 6207
signum 15


However, I have scripts that do chained commands, ie /foo/bar.sh; some_other_script.py. Under this scenario, the signal is not passed to the final script:



$ /bin/sh -c "echo foo; python ~/tmpcode/signal_test.py" &
[8] 8015
$ kill 8015


Same thing happens if I try && instead of ;
Im trying to understand whats going on here, and if there is a way to get the signal to chain through.
Side point: The main reason the script is running multi-chain commands is because the first command sets up some environment for the second one to use.



signal_test.py:



import time
import signal
import sys

def handler( signum, frame ):
print( "signum %dn" % signum )
sys.exit(signum)

signal.signal( signal.SIGTERM, handler )
time.sleep(60)









share|improve this question















Im trying to understand why signals arent being passed properly under this setup.
Simple test, I have a python script that registers a sigterm handler and prints if it gets it. I have verified this works if i run it and send a TERM.



However, I happen to be running this as a python Subprocess with useShell = True. useShell launches the command with /bin/sh -c ...



If I do this, it actually works as well:



$/bin/sh -c "python ~/tmpcode/signal_test.py" &
[8] 6207
$ kill 6207
signum 15


However, I have scripts that do chained commands, ie /foo/bar.sh; some_other_script.py. Under this scenario, the signal is not passed to the final script:



$ /bin/sh -c "echo foo; python ~/tmpcode/signal_test.py" &
[8] 8015
$ kill 8015


Same thing happens if I try && instead of ;
Im trying to understand whats going on here, and if there is a way to get the signal to chain through.
Side point: The main reason the script is running multi-chain commands is because the first command sets up some environment for the second one to use.



signal_test.py:



import time
import signal
import sys

def handler( signum, frame ):
print( "signum %dn" % signum )
sys.exit(signum)

signal.signal( signal.SIGTERM, handler )
time.sleep(60)






python linux bash shell






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 '18 at 1:44







ByteMe95

















asked Nov 9 '18 at 14:23









ByteMe95ByteMe95

1888




1888







  • 1




    That is because Python process will have a different process id.
    – user902384
    Nov 9 '18 at 14:27










  • @user902384 That doesn't explain how signal_test.py gets the signal in the first question.
    – chepner
    Nov 9 '18 at 15:06










  • But in the first example, sh may be optimized to use exec to run the single specified command, meaning 6207 is the Python process. In the second example, sh is instead forking a new process for Python. (If you show the contents of signal_test.py, we could probably suggest how to confirm this hypothesis.)
    – chepner
    Nov 9 '18 at 15:13










  • Might also help to see ps -fu $LOGNAME, and maybe trap.
    – Paul Hodges
    Nov 9 '18 at 15:49







  • 1




    @ByteMe95 How does kill 6207 (which sends SIGTERM to a process) get processed by your script (which only installs a handler for SIGKILL)?
    – chepner
    Nov 10 '18 at 14:29












  • 1




    That is because Python process will have a different process id.
    – user902384
    Nov 9 '18 at 14:27










  • @user902384 That doesn't explain how signal_test.py gets the signal in the first question.
    – chepner
    Nov 9 '18 at 15:06










  • But in the first example, sh may be optimized to use exec to run the single specified command, meaning 6207 is the Python process. In the second example, sh is instead forking a new process for Python. (If you show the contents of signal_test.py, we could probably suggest how to confirm this hypothesis.)
    – chepner
    Nov 9 '18 at 15:13










  • Might also help to see ps -fu $LOGNAME, and maybe trap.
    – Paul Hodges
    Nov 9 '18 at 15:49







  • 1




    @ByteMe95 How does kill 6207 (which sends SIGTERM to a process) get processed by your script (which only installs a handler for SIGKILL)?
    – chepner
    Nov 10 '18 at 14:29







1




1




That is because Python process will have a different process id.
– user902384
Nov 9 '18 at 14:27




That is because Python process will have a different process id.
– user902384
Nov 9 '18 at 14:27












@user902384 That doesn't explain how signal_test.py gets the signal in the first question.
– chepner
Nov 9 '18 at 15:06




@user902384 That doesn't explain how signal_test.py gets the signal in the first question.
– chepner
Nov 9 '18 at 15:06












But in the first example, sh may be optimized to use exec to run the single specified command, meaning 6207 is the Python process. In the second example, sh is instead forking a new process for Python. (If you show the contents of signal_test.py, we could probably suggest how to confirm this hypothesis.)
– chepner
Nov 9 '18 at 15:13




But in the first example, sh may be optimized to use exec to run the single specified command, meaning 6207 is the Python process. In the second example, sh is instead forking a new process for Python. (If you show the contents of signal_test.py, we could probably suggest how to confirm this hypothesis.)
– chepner
Nov 9 '18 at 15:13












Might also help to see ps -fu $LOGNAME, and maybe trap.
– Paul Hodges
Nov 9 '18 at 15:49





Might also help to see ps -fu $LOGNAME, and maybe trap.
– Paul Hodges
Nov 9 '18 at 15:49





1




1




@ByteMe95 How does kill 6207 (which sends SIGTERM to a process) get processed by your script (which only installs a handler for SIGKILL)?
– chepner
Nov 10 '18 at 14:29




@ByteMe95 How does kill 6207 (which sends SIGTERM to a process) get processed by your script (which only installs a handler for SIGKILL)?
– chepner
Nov 10 '18 at 14:29












1 Answer
1






active

oldest

votes


















2














Let me explain the details.



The number bash returned is not pid, it is pgid (process group id)



When you run a command in the shell, shell will create a new process group. The group will contain all process in the command. And the pgid is the same as pid of the leader process.



A process group means task in the word multi-task, shell is able to switch between groups using bg(^Z)/fg. All signal (like ^C) generated by shell (acturaly pty, another story) will send to the entire group instead of leader process.



When shell creates multiple processes or single process ?



The answer is obviously, the shell will create multiple processes when the commands can't be handled by a single process.



In the first example



$/bin/sh -c "python ~/tmpcode/signal_test.py" &
[8] 6207


a single command is issued, so the sub-shell itself (/bin/sh) becomes python. Notes, even there is only one process, there still be a new process group containing the only process.



In the second example



$ /bin/sh -c "echo foo; python ~/tmpcode/signal_test.py" &
[8] 8015


two commands are issued, the task can't be achieved by a single process, so multiple process is needed:



/bin/sh
echo
python


A process group is created containing these three process.



How to send signals to process group ?



Use



kill <SIGNAL> -<pgid>


The minus sign in front of pgid is essential.






share|improve this answer






















  • I don't think there's any requirement that the shell detect when it could simply exec rather than forking; that's an implementation-dependent optimization (which could be confirmed using strace or the like).
    – chepner
    Nov 12 '18 at 14:43










  • @chepner maybe my answer is a bit misleading, but my point is that you should always treat the number as pgid instead of pid. I don't care about how many process are there at all.
    – Zang MingJie
    Nov 14 '18 at 6:33











  • Fair enough. Sending a signal to a process group means that each process receives the signal directly from the OS, though, rather than the group leader passing it to its children, right? (A subtle distinction, but it would mean, among other things, the group leader doesn't get to decide who receives the signal.)
    – chepner
    Nov 14 '18 at 12:58










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
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%2fstackoverflow.com%2fquestions%2f53227532%2flinux-signal-not-passed-to-multi-command%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









2














Let me explain the details.



The number bash returned is not pid, it is pgid (process group id)



When you run a command in the shell, shell will create a new process group. The group will contain all process in the command. And the pgid is the same as pid of the leader process.



A process group means task in the word multi-task, shell is able to switch between groups using bg(^Z)/fg. All signal (like ^C) generated by shell (acturaly pty, another story) will send to the entire group instead of leader process.



When shell creates multiple processes or single process ?



The answer is obviously, the shell will create multiple processes when the commands can't be handled by a single process.



In the first example



$/bin/sh -c "python ~/tmpcode/signal_test.py" &
[8] 6207


a single command is issued, so the sub-shell itself (/bin/sh) becomes python. Notes, even there is only one process, there still be a new process group containing the only process.



In the second example



$ /bin/sh -c "echo foo; python ~/tmpcode/signal_test.py" &
[8] 8015


two commands are issued, the task can't be achieved by a single process, so multiple process is needed:



/bin/sh
echo
python


A process group is created containing these three process.



How to send signals to process group ?



Use



kill <SIGNAL> -<pgid>


The minus sign in front of pgid is essential.






share|improve this answer






















  • I don't think there's any requirement that the shell detect when it could simply exec rather than forking; that's an implementation-dependent optimization (which could be confirmed using strace or the like).
    – chepner
    Nov 12 '18 at 14:43










  • @chepner maybe my answer is a bit misleading, but my point is that you should always treat the number as pgid instead of pid. I don't care about how many process are there at all.
    – Zang MingJie
    Nov 14 '18 at 6:33











  • Fair enough. Sending a signal to a process group means that each process receives the signal directly from the OS, though, rather than the group leader passing it to its children, right? (A subtle distinction, but it would mean, among other things, the group leader doesn't get to decide who receives the signal.)
    – chepner
    Nov 14 '18 at 12:58















2














Let me explain the details.



The number bash returned is not pid, it is pgid (process group id)



When you run a command in the shell, shell will create a new process group. The group will contain all process in the command. And the pgid is the same as pid of the leader process.



A process group means task in the word multi-task, shell is able to switch between groups using bg(^Z)/fg. All signal (like ^C) generated by shell (acturaly pty, another story) will send to the entire group instead of leader process.



When shell creates multiple processes or single process ?



The answer is obviously, the shell will create multiple processes when the commands can't be handled by a single process.



In the first example



$/bin/sh -c "python ~/tmpcode/signal_test.py" &
[8] 6207


a single command is issued, so the sub-shell itself (/bin/sh) becomes python. Notes, even there is only one process, there still be a new process group containing the only process.



In the second example



$ /bin/sh -c "echo foo; python ~/tmpcode/signal_test.py" &
[8] 8015


two commands are issued, the task can't be achieved by a single process, so multiple process is needed:



/bin/sh
echo
python


A process group is created containing these three process.



How to send signals to process group ?



Use



kill <SIGNAL> -<pgid>


The minus sign in front of pgid is essential.






share|improve this answer






















  • I don't think there's any requirement that the shell detect when it could simply exec rather than forking; that's an implementation-dependent optimization (which could be confirmed using strace or the like).
    – chepner
    Nov 12 '18 at 14:43










  • @chepner maybe my answer is a bit misleading, but my point is that you should always treat the number as pgid instead of pid. I don't care about how many process are there at all.
    – Zang MingJie
    Nov 14 '18 at 6:33











  • Fair enough. Sending a signal to a process group means that each process receives the signal directly from the OS, though, rather than the group leader passing it to its children, right? (A subtle distinction, but it would mean, among other things, the group leader doesn't get to decide who receives the signal.)
    – chepner
    Nov 14 '18 at 12:58













2












2








2






Let me explain the details.



The number bash returned is not pid, it is pgid (process group id)



When you run a command in the shell, shell will create a new process group. The group will contain all process in the command. And the pgid is the same as pid of the leader process.



A process group means task in the word multi-task, shell is able to switch between groups using bg(^Z)/fg. All signal (like ^C) generated by shell (acturaly pty, another story) will send to the entire group instead of leader process.



When shell creates multiple processes or single process ?



The answer is obviously, the shell will create multiple processes when the commands can't be handled by a single process.



In the first example



$/bin/sh -c "python ~/tmpcode/signal_test.py" &
[8] 6207


a single command is issued, so the sub-shell itself (/bin/sh) becomes python. Notes, even there is only one process, there still be a new process group containing the only process.



In the second example



$ /bin/sh -c "echo foo; python ~/tmpcode/signal_test.py" &
[8] 8015


two commands are issued, the task can't be achieved by a single process, so multiple process is needed:



/bin/sh
echo
python


A process group is created containing these three process.



How to send signals to process group ?



Use



kill <SIGNAL> -<pgid>


The minus sign in front of pgid is essential.






share|improve this answer














Let me explain the details.



The number bash returned is not pid, it is pgid (process group id)



When you run a command in the shell, shell will create a new process group. The group will contain all process in the command. And the pgid is the same as pid of the leader process.



A process group means task in the word multi-task, shell is able to switch between groups using bg(^Z)/fg. All signal (like ^C) generated by shell (acturaly pty, another story) will send to the entire group instead of leader process.



When shell creates multiple processes or single process ?



The answer is obviously, the shell will create multiple processes when the commands can't be handled by a single process.



In the first example



$/bin/sh -c "python ~/tmpcode/signal_test.py" &
[8] 6207


a single command is issued, so the sub-shell itself (/bin/sh) becomes python. Notes, even there is only one process, there still be a new process group containing the only process.



In the second example



$ /bin/sh -c "echo foo; python ~/tmpcode/signal_test.py" &
[8] 8015


two commands are issued, the task can't be achieved by a single process, so multiple process is needed:



/bin/sh
echo
python


A process group is created containing these three process.



How to send signals to process group ?



Use



kill <SIGNAL> -<pgid>


The minus sign in front of pgid is essential.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 12 '18 at 4:03

























answered Nov 12 '18 at 3:56









Zang MingJieZang MingJie

4,116922




4,116922











  • I don't think there's any requirement that the shell detect when it could simply exec rather than forking; that's an implementation-dependent optimization (which could be confirmed using strace or the like).
    – chepner
    Nov 12 '18 at 14:43










  • @chepner maybe my answer is a bit misleading, but my point is that you should always treat the number as pgid instead of pid. I don't care about how many process are there at all.
    – Zang MingJie
    Nov 14 '18 at 6:33











  • Fair enough. Sending a signal to a process group means that each process receives the signal directly from the OS, though, rather than the group leader passing it to its children, right? (A subtle distinction, but it would mean, among other things, the group leader doesn't get to decide who receives the signal.)
    – chepner
    Nov 14 '18 at 12:58
















  • I don't think there's any requirement that the shell detect when it could simply exec rather than forking; that's an implementation-dependent optimization (which could be confirmed using strace or the like).
    – chepner
    Nov 12 '18 at 14:43










  • @chepner maybe my answer is a bit misleading, but my point is that you should always treat the number as pgid instead of pid. I don't care about how many process are there at all.
    – Zang MingJie
    Nov 14 '18 at 6:33











  • Fair enough. Sending a signal to a process group means that each process receives the signal directly from the OS, though, rather than the group leader passing it to its children, right? (A subtle distinction, but it would mean, among other things, the group leader doesn't get to decide who receives the signal.)
    – chepner
    Nov 14 '18 at 12:58















I don't think there's any requirement that the shell detect when it could simply exec rather than forking; that's an implementation-dependent optimization (which could be confirmed using strace or the like).
– chepner
Nov 12 '18 at 14:43




I don't think there's any requirement that the shell detect when it could simply exec rather than forking; that's an implementation-dependent optimization (which could be confirmed using strace or the like).
– chepner
Nov 12 '18 at 14:43












@chepner maybe my answer is a bit misleading, but my point is that you should always treat the number as pgid instead of pid. I don't care about how many process are there at all.
– Zang MingJie
Nov 14 '18 at 6:33





@chepner maybe my answer is a bit misleading, but my point is that you should always treat the number as pgid instead of pid. I don't care about how many process are there at all.
– Zang MingJie
Nov 14 '18 at 6:33













Fair enough. Sending a signal to a process group means that each process receives the signal directly from the OS, though, rather than the group leader passing it to its children, right? (A subtle distinction, but it would mean, among other things, the group leader doesn't get to decide who receives the signal.)
– chepner
Nov 14 '18 at 12:58




Fair enough. Sending a signal to a process group means that each process receives the signal directly from the OS, though, rather than the group leader passing it to its children, right? (A subtle distinction, but it would mean, among other things, the group leader doesn't get to decide who receives the signal.)
– chepner
Nov 14 '18 at 12:58

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • 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.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • 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%2fstackoverflow.com%2fquestions%2f53227532%2flinux-signal-not-passed-to-multi-command%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

Use pre created SQLite database for Android project in kotlin

Darth Vader #20

Ondo