26

I have a problem regarding how to kill a process in Cygwin on Windows. I am completely new to Cygwin. But I have a task that I simply cant kill. I have tried issuing the following commands:

kill 4568
kill -9 4568
/bin/kill -f 4568

I have issued the commands in a separate Cygwin terminal since I cannot Ctrl+C it in the Cygwin terminal where the process run. I have searched all over the internet without success.

4
  • What's the process you started, and how did you start it?
    – me_and
    Jun 1, 2012 at 11:27
  • See also stackoverflow.com/questions/10877652/…
    – me_and
    Jun 21, 2012 at 9:18
  • I'm very surprised that /bin/kill -f didn't kill it- it's my "nuclear option" when all else fails.
    – AJM
    Jan 17, 2023 at 16:57
  • If you know that it is a Windows process, and if you also know its Windows PID, you could use taskkill. Dec 15, 2023 at 12:09

9 Answers 9

30
ps -W | awk '/calc.exe/,NF=1' | xargs kill -f

Or

ps -W | awk '$0~v,NF=1' v=calc.exe | xargs kill -f

Or

powershell kill -n calc
2
  • 1
    You may want to use ps -W | awk 'BEGIN{ IGNORECASE=1;} /calc.exe/,NF=1' | xargs kill -f because Windows is case-insensitive
    – tricasse
    Nov 7, 2017 at 13:46
  • 2
    Make sure you use /bin/kill, the bash builtin kill doesn't have the -f switch. Using /bin/kill seems to work on git-bash, msys2 and cygwin.
    – cdleonard
    Mar 30, 2023 at 6:54
10

You may try:

taskkill /pid 4568
5
  • taskkill /im:{name-of-executable} is useful as well.
    – LawrenceC
    Jun 25, 2012 at 23:54
  • and taskkill /im <name-of-exe> /f is even more useful. Sep 16, 2012 at 15:36
  • 2
    Bad answer, the OP asked for a Cygwin command. Aug 14, 2017 at 2:27
  • 4
    It's taskkill //im <name-of-exe> (note the need for 2 slashes) Feb 28, 2018 at 16:35
  • Cygwin and related environments like git-bash and msys have no problems running windows native utilities so this is a good answer.
    – cdleonard
    Mar 30, 2023 at 6:55
10

If you want a BASH only solution, try this: (it works for me)

    KILLPS="<My Process Name>"
    WINPS=`ps -W | grep -i $KILLPS`         # Make case-insensitive.
    PID=`echo $WINPS | cut -d' ' -f1` 
    /bin/kill -f "$PID"

NOTE: use /bin/kill, the embedded shell kill will not kill PIDs for general windows proccesses.

2
  • 4
    Your note about /bin/kill vs shell kill was very useful. Thanks
    – Phil
    May 9, 2017 at 21:08
  • 2
    Like @Phil I also found the distinction between kill and /bin/kill to be unexpected, informative and ultimately very useful in stopping troublesome processes. Thanks!
    – AJM
    Jan 16, 2023 at 13:44
2

(From my answer to a similar question on SO):

Different Windows programs will handle the signals that kill sends differently; they've never been designed to deal with them in the same way that Linux/Cygwin programs are.

The only reliable method for killing a Windows program is to use a Windows specific tool, such as Task Manager or Process Explorer.

That said, if you've not already, you may have luck with running your Cygwin terminal in administrator mode (right click on your shortcut and select "Run as administrator").

2

Two things to think about here:

  1. Get the correct PID, which is the WINPID.
  2. Use the right tool.

To get the correct WINPID to kill, use cat /proc/<PID>/winpid. I.e. run this:

ZID=$$; WINPID=$(cat /proc/${ZID}/winpid); echo "Kill WINPID: ${WINPID}"; ps; sleep 10 &
 

and immediately after do another ps.

The right tool to use is Sysinternals' PsKill64.exe -t <winpid> which also kills all descendants of the script process, which kill doesn't.

3
  • 1
    You got a vote for cat /proc/${ZID}/winpid, very good to know. And faster than solution with ps -aW | grep ..., at least on my cygwin under Win 7 x64. But for PsKill64 I think you need -t to kill sub processes, and taskkill can also kill subprocesses.
    – 244an
    Dec 19, 2017 at 21:40
  • Yes, you also need the -t to kill descendants. Corrected answer.
    – not2qubit
    Dec 20, 2017 at 14:47
  • I like this because you can access the command-line, but unfortunately it doesn't find all processes like children spawned by commands.
    – Wheezil
    Aug 31, 2021 at 20:44
1

If you have a Windows program that is a subprocess under a cygwin bash process you can use taskkill /F /PID [the cygwin process id] /T to kill the process tree, no need to get the Window PID from ps with awk etc.
This is tested under Win7 x64.

# Simple example in cygwin:
> notepad.exe &
> pid=$!
...
> taskkill /F /PID $pid /T

Of course you can use the Window PID also.

0

In Git Bash I use:

targetProcess='chromedriver.exe';
ps -W | grep -i ${targetProcess} | awk '{print $1}' | while read pid; do taskkill //PID ${pid}; done;

I have not tried it in Cygwin, but I suppose it will work there too.

0

Extending other answers, I found this to be a useful pattern. Note cutting the WINPID column:

for pid in `ps -W | grep 'processname' | tr -s ' ' | cut -d ' ' -f 5`
do
    echo killing $pid
    taskkill /F /pid $pid
done
0

TL;DR: wmic process get ProcessID, Commandline /format:csv | tr -d '\r' | grep -- 'search term' | awk -F, '{ print $NF }' | xargs /bin/kill -f -W


I had a more challenging situation than most answers considered: killing the Windows process by executable name (node.exe) was too broad so I had to find the WINPID by looking at the command line arguments. And unfortunately, the cygwin ps command doesn't show commandline arguments.

Another challenge was, although my process was spawned in cygwin, it created child processes that couldn't be seen in any ps except ps -W.

As an aside, you can find command line arguments for your visible cygwin processes by running this: grep -a "" /proc/*/cmdline | xargs -0 But that didn't help me in this situation because the process I wanted to kill wasn't visible by cygwin and therefore wasn't in that output.

Fortunately, Windows (10, at least) comes with a command line tool you can run in cygwin to get command name and argument information. Here's how: wmic process get ProcessID, Commandline /format:csv. The output looks something like this:

DESKTOP-ABC,E:\Windows\system32\lxss\wslhost.exe {xxx} x y z {xxx},180
DESKTOP-ABC,\??\E:\Windows\system32\conhost.exe 0x6,2295
DESKTOP-ABC,E:\Windows\system32\svchost.exe -k ClipboardSvcGroup -p -s abcdef,430

The last column of that output is the Windows process ID.

Other answers here claim you can /bin/kill -f $WINPID those, but when I tried, it reported this error: kill: illegal pid: $WINPID. I suspect this has something to do with cygwin not running in administrator mode? [No, this was not why, see my update below, but it is written in a way that assumes you've read the original first.*]

Original Answer (1/3/2023)

Additional answers say to taskkill /pid $WINPID but when I tried, it reported this error: ERROR: Invalid query. But this line from @244an's answer worked for me: taskkill /F /PID $WINPID /T.

I decided to post this as a separate answer because, in my humble opinion, the information I've written above is just as valuable as @244an's answer, and I have more to say. taskkill provides a variety of ways to get the Windows PID from the cygwin command line even if the process isn't visible in cygwin.

I also want to say it was challenging to figure out how to pass a variable into taskkill due to line return issues. wmic, being a Windows command, returns Windows line endings (\r\n). Cygwin assumes its commands are going to receive unix endings (\n). Due to this, taskkill outputs some very unhelpful error messages. The tr in this pipeline is how I resolved that:

wmic process get ProcessID, Commandline /format:csv | tr -d '\r' | grep -- 'search term' | awk -F, '{ system("taskkill /F /PID " $NF " /T") }'

It removes every '\r' from the output. awk -F, means the field separator for every column is a comma. The rest of the awk command says, "for every line grep finds, run taskkill on the last column (i.e., $NF) of the csv output.

Updated Answer (1/3/2024)

*: As @Roy pointed out in a comment, this was probably because I was not including the -W flag. In other words, I should've typed /bin/kill -f -W $WINPID instead of /bin/kill -f $WINPID.

Here's another important aside: I didn't even know -W existed because it never came up in the man page or kill's usage message. Another comment explains why, but I couldn't understand it (until today):

Make sure you use /bin/kill, the bash builtin kill doesn't have the -f switch. Using /bin/kill seems to work on git-bash, msys2 and cygwin.

Here's my understanding: if you type kill on the command line when using bash with cygwin, it uses the bash builtin. That is not the same as /bin/kill: /bin/kill is a cygwin command, and it's the one that has the -f and -W flags.

It turns out /bin/kill -f -W $WINPID is even better than taskkill /F /PID $WINPID /T. Today, it allowed me to kill a process that taskkill /F /PID $WINPID /T couldn't. It also simplifies the script at the end of my original answer. Now it looks like this:

wmic process get ProcessID, Commandline /format:csv | tr -d '\r' | grep -- 'search term' | awk -F, '{ print $NF }' | xargs /bin/kill -f -W
5
  • 1
    "Other answers here claim you can /bin/kill -f $WINPID" --- it works if you include the -W flag, too: /bin/kill -f -W $WINPID
    – Rop
    Nov 26, 2023 at 22:01
  • @Rop what do you mean by the word, "too?" Are you saying /bin/kill -f $WINPID worked without that flag? Nov 27, 2023 at 23:06
  • no i didnt mean that :) --- i meant, you must ALSO include the -W flag.
    – Rop
    Nov 28, 2023 at 10:57
  • 1
    @Rop Wow, I just tried this and it killed processes that I could NOT kill with taskkill /F /PID $PID /T. Out of curiosity, how did you learn that? I can't find kill's -W documented anywhere, including the info kill page and the kill usage message. Jan 4 at 1:57
  • 1
    Daniel Kaplan: it's cygwin specific, and documented here: cygwin.com/cygwin-ug-net/ps.html
    – Rop
    Jan 9 at 7:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .