How do I disown/detach a process from the Git Bash terminal that come with Git's Windows installer?
I would like to run commands from the terminal (mostly Python servers) and essentially daemonize them. I am running the MinGW terminal "Git Bash" that comes with the Windows installer for Git.
Things tried that do not work:
- nohup -> command not found
- setsid -> command not found
-
$ script.py &
-> does not behave as expected -
$ script.py & disown
-> does not behave as expected
I would use bg
, but my end-goal is to close the terminal after my servers are all running and not kill the processes.
Solution 1:
This is a synthesis from my longer answer to a similar question in SO.
If your app logs to stdout/stderr, use:
cmd //c start cmd //k "path\\to\\script-dir\\script.py"
If it logs to files, via sockets etc. and you do not need stdout/stderr, use:
cmd //c start //D "path\\to\\script-dir" script.py
In both cases you get a daemon like process which will survive when you close bash. In the first instance your script is hosted in a visible cmd.exe
window.
Much more here.
Solution 2:
Simply prefix your command with start
.
E.g.
start TortoiseGitProc /command:showcompare /revision1:master /revision2:HEAD
The spawned process inherits the current working directory.
Solution 3:
The mixture of cmd
and start
does work, although both of @antonio 's solutions were "visible" for me. I was trying to find another way, more consistent with MinGW.
TL;DR
mintty bash -mc "commands &>/dev/null < /dev/null &"
seems to always work
I'm not sure what has all changed since this original post, but using 2.31.1 now, and run git for window's bash
in a few different ways.
A subset of what I tried
Here are my results
-
In
mintty
(the "normal" way)- Stdin on mintty is a pipe rather than a tty and would require
winpty
in order to get a tty (no idea if this matters)
I would execute these commands, then close mintty
Command Works? git gui
Nope, the command git
is called here, and hooked in, so closing she shell kill the git commandgit-gui
Works, although this is not calling the CLI git anymore, but the windows GUI executable directly, git-gui
. This is not a general solutionsleep 60
Nope sleep 60&
Only if you press Ctrl+D to close, instead of click the X or pressing Alt+F4 bash -c "sleep 60&"
Yes (Still get a warning when you close mintty, but it doesn't kill sleep
)mintty bash -c "sleep 60&"
Nope mintty bash -mc "sleep 60&"
Yes, fully detached ./foo.bat&
Nope, foo.bat
uses stdout, needs to be redirected./foo.bat < /dev/null&
Only if you press Ctrl+D to close, instead of click the X or pressing Alt+F4 mintty bash -mc "./foo.bat < /dev/null&"
Yes, fully detached winpty bash -mc "./foo.bat&"
Nope, when stdin is close, the pty dies winpty bash -c "./foo.bat&" < /dev/null
Does not work the first time, works on additional calls winpty bash -mc "./foo.bat&" < /dev/null
Only works like half the time, random winpty bash -c "./foo.bat" < /dev/null &
Only works like half the time, random /c/Python39/python foo.py
Same result as sleep
/foo.bat
- Stdin on mintty is a pipe rather than a tty and would require
-
In PowerShell
- Running in powershell does gives stdin a tty
Showing different results only
Command Works? sleep 60&
Nope bash -c "sleep 60&"
Nope ./foo.bat < /dev/null&
Nope mintty bash -mc "./foo.bat < /dev/null&"
Nope mintty bash -mc "./foo.bat &> /dev/null < /dev/null&"
Yes winpty bash -c "./foo.bat&" < /dev/null
Nope winpty bash -c "./foo.bat&" &> /dev/null < /dev/null
Works half the time, even the first time winpty bash -mc "./foo.bat&" < /dev/null
Nope winpty bash -mc "./foo.bat&" &> /dev/null < /dev/null
Works half the time winpty bash -mc "./foo.bat" &> /dev/null < /dev/null &
Works half the time
Main difference: First three lines don't work, and stdout/stderr had to be redirected. Which is interesting in the case where a new mintty
is spawned.
-
In Command Prompt (cmd)
- Running in cmd does gives stdin a tty
- Results same as PowerShell
-
In Windows Terminal
- Running in W Terminal does gives stdin a tty
- Results same as PowerShell
What's going on here
-
I was attempting to detach stdin/stdout/stderr/and tty
-
Some of my earlier tests got
TTY
to say?
inps
, however that did not help -
Based off of the observations with
start
/cmd
, I was able to get a combo that usedmintty
. I imagine this will handle more cases when it comes to nested quotes, as this keeps the call within the GNU arguments arena, should the need arise. -
It took me a while to find the
winpty
/redirect/bg combo that worked, then I found out that if I try it 10 times in a row, it might work 3 times, it might work 8 times, but usually not 10. It's completely unstable-
I could now find out why, even using:
for s in
seq 10
; do winpty bash -c './foo.bat &> foo.$$' < /dev/null; done -
Not all 10 foo.# files even existed, telling me the bash command didn't even start to get executed.
-
winpty
executes additional path translation on arguments inconsistent with MinGW's path translations rules, so usingwinpty
is generally asking for trouble
-
-
disown
in bash on MinGW appears to do nothing for or against this endeavor.
Solution 4:
I have no idea if this will work in bash in Windows, but bash provides a built-in command to "disown" a background process. After you've backgrounded the job with bg
just run disown
. By default it will disown the most recently bg
-ed job, but you can also give it a job number if you have multiple background jobs.
More info here on Job control built-ins.