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.

Zombo
  • 1

9 Answers9

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
Zombo
  • 1
10

You may try:

taskkill /pid 4568
aggu
  • 182
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.

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

AJM
  • 500
not2qubit
  • 2,651
  • 4
  • 34
  • 45
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").

me_and
  • 2,267
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.

244an
  • 111
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
Wheezil
  • 101
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