-
Versions: python 3.11.7 Hi! I'm encountering a weird issue with pyisntaller and my script. I have a python script that executes a subprocess in a interactive way. I want the process to handle the signals (CTRL+Z, CTRL+C, etc) but instead when I press those keys the python execution hangs. My program does something like this (simplified): (...)
cmd = f"ssh -i {key} {user}@{server}"
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGQUIT, signal.SIG_IGN)
signal.signal(signal.SIGTSTP, signal.SIG_IGN)
subprocess.run(cmd, shell=True)
(...) The idea is that python runs the command and then all signals (CTRL+Z, CTRL+C, etc) are handled by the command (ssh). This way, if I go into a server using this, i can CTRL+C a command i'm running:
What I'm seeing is exactly the same as this comment on stack overflow: This doesn't happen if I run the command with python: python mycommand.py -k key -u user -s server # works as expected with CTRL+Z
./dist/mycommand -k key -u user -s server # exits python whith CTRL+Z Do you have any ideas as to why this happens? |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments
-
Note that CTRL + C is handled correctly, while logged in i can press ctrl c and the process doesn't end:
Also I've tried using the flag
This is the command i use to buld the package:
|
Beta Was this translation helpful? Give feedback.
-
I've seen this, but doesn't seem fixed: |
Beta Was this translation helpful? Give feedback.
-
Signals are somewhat messy in I think In a On the other hand, if you press Ctrl+C, both parent and child receive the signal (because the signal was sent to process group, and both those processes are in it). But parent ignores the signal and forwards it to the child, who now receives two signals - one from process group and one from the parent. This can, depending on timing, lead to exception being thrown while python attempts to handle the signal. And I think the Which brings us to Ctrl+Z and SIGTSTP. If you wanted to stop a onefile application, you would need to stop both parent and child process. Which means that the PyInstaller's default behavior of ignoring the signal in parent and forwarding it to the child is wrong - that's why #4244 added SIGSTP to the list of exceptions for which signal handlers in the parent process are not modified. This ensures that if Ctrl+Z is pressed, both processes are suspended. It does not work if you send SIGTSTP directly to parent, though; you will suspend the parent, but not the child. On the flip side, though, it prevents the child process from receiving two SIGTSTP signals when Ctrl+Z is pressed (which might or might not be problematic in a similar way as it is from Ctrl+C). And lastly, your use-case is different from what was discussed so far. You want SIGTSTP handling disabled in both the parent process and in the child process, so that when SIGTSTP is sent to process group on Ctrl+Z, none of the processes are suspended, and only the spawned ssh program acts upon it. And while you have successfully disabled signal handling in the child process (via python's So if you really want to achieve the behavior you describe, and want to use pyinstaller/bootloader/src/pyi_utils.c Lines 1070 to 1077 in 18d5325 and ensure that the custom |
Beta Was this translation helpful? Give feedback.
-
Hi! Thank you very much for your answer, now I understand it a lot more! I think I was getting obsessed with having the isntallation in one file only, but it's not that practical anyway. I'm going to try with your approach and test! |
Beta Was this translation helpful? Give feedback.
Signals are somewhat messy in
onefile
builds, because it has a parent and a child process, and the semantics of passing the signals between the two are ill-posed in some cases, due to issue of sending signal to parent process (e.g., viakill -SIGNUM <pid>
) and sending signal to whole process group (which is what pressing Ctrl+C or Ctrl+Z in your terminal actually does).I think
onedir
build of your example program would behave as you expect, i.e., similar to unfrozen python. Your python code disables the signal handling in program process, so if you send SIGINT or SIGTSTP to it viakill
, nothing happens. That's also why if you press Ctrl+C or Ctrl+Z, the program ignores the signal it rece…